1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-03-12 08:58:20 +03:00

Merge pull request #7512 from yuwata/mount-create-dir

fixes related to systemd-mount and chase_symlinks()
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2017-12-05 10:49:25 +01:00 committed by GitHub
commit 98b518628f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 30 deletions

View File

@ -621,10 +621,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
* Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
* as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
* function what to do when encountering a symlink with an absolute path as directory: prefix it by the
* specified path.
*
* Note: there's also chase_symlinks_prefix() (see below), which as first step prefixes the passed path by the
* passed root. */
* specified path. */
if (original_root) {
r = path_make_absolute_cwd(original_root, &root);
@ -722,6 +719,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
* what we got so far. But don't allow this if the remaining path contains "../ or "./"
* or something else weird. */
/* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
if (streq_ptr(done, "/"))
*done = '\0';
if (!strextend(&done, first, todo, NULL))
return -ENOMEM;
@ -794,6 +795,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
done = first;
first = NULL;
} else {
/* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
if (streq(done, "/"))
*done = '\0';
if (!strextend(&done, first, NULL))
return -ENOMEM;
}

View File

@ -30,6 +30,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "fstab-util.h"
#include "mount-util.h"
#include "pager.h"
@ -333,19 +334,15 @@ static int parse_argv(int argc, char *argv[]) {
return log_oom();
} else if (arg_transport == BUS_TRANSPORT_LOCAL) {
_cleanup_free_ char *u = NULL, *p = NULL;
_cleanup_free_ char *u = NULL;
u = fstab_node_to_udev_node(argv[optind]);
if (!u)
return log_oom();
r = path_make_absolute_cwd(u, &p);
r = chase_symlinks(u, NULL, 0, &arg_mount_what);
if (r < 0)
return log_error_errno(r, "Failed to make path %s absolute: %m", u);
arg_mount_what = canonicalize_file_name(p);
if (!arg_mount_what)
return log_error_errno(errno, "Failed to canonicalize path %s: %m", p);
} else {
arg_mount_what = strdup(argv[optind]);
if (!arg_mount_what)
@ -361,16 +358,9 @@ static int parse_argv(int argc, char *argv[]) {
if (argc > optind+1) {
if (arg_transport == BUS_TRANSPORT_LOCAL) {
_cleanup_free_ char *p = NULL;
r = path_make_absolute_cwd(argv[optind+1], &p);
r = chase_symlinks(argv[optind+1], NULL, CHASE_NONEXISTENT, &arg_mount_where);
if (r < 0)
return log_error_errno(r, "Failed to make path %s absolute: %m", argv[optind+1]);
arg_mount_where = canonicalize_file_name(p);
if (!arg_mount_where)
return log_error_errno(errno, "Failed to canonicalize path %s: %m", p);
} else {
arg_mount_where = strdup(argv[optind+1]);
if (!arg_mount_where)
@ -829,7 +819,7 @@ static int stop_mount(
r = unit_name_from_path(where, suffix, &mount_unit);
if (r < 0)
return log_error_errno(r, "Failed to make mount unit name from path %s: %m", where);
return log_error_errno(r, "Failed to make %s unit name from path %s: %m", suffix + 1, where);
r = sd_bus_message_new_method_call(
bus,
@ -853,8 +843,12 @@ static int stop_mount(
polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0)
return log_error_errno(r, "Failed to stop mount unit: %s", bus_error_message(&error, r));
if (r < 0) {
if (streq(suffix, ".automount") &&
sd_bus_error_has_name(&error, "org.freedesktop.systemd1.NoSuchUnit"))
return 0;
return log_error_errno(r, "Failed to stop %s unit: %s", suffix + 1, bus_error_message(&error, r));
}
if (w) {
const char *object;
@ -991,26 +985,19 @@ static int action_umount(
}
for (i = optind; i < argc; i++) {
_cleanup_free_ char *u = NULL, *a = NULL, *p = NULL;
_cleanup_free_ char *u = NULL, *p = NULL;
struct stat st;
u = fstab_node_to_udev_node(argv[i]);
if (!u)
return log_oom();
r = path_make_absolute_cwd(u, &a);
r = chase_symlinks(u, NULL, 0, &p);
if (r < 0) {
r2 = log_error_errno(r, "Failed to make path %s absolute: %m", argv[i]);
continue;
}
p = canonicalize_file_name(a);
if (!p) {
r2 = log_error_errno(errno, "Failed to canonicalize path %s: %m", argv[i]);
continue;
}
if (stat(p, &st) < 0)
return log_error_errno(errno, "Can't stat %s (from %s): %m", p, argv[i]);

View File

@ -168,6 +168,26 @@ static void test_chase_symlinks(void) {
assert_se(r > 0 && path_equal(result, "/etc"));
result = mfree(result);
r = chase_symlinks("/../.././//../../etc", NULL, 0, &result);
assert_se(r > 0);
assert_se(streq(result, "/etc"));
result = mfree(result);
r = chase_symlinks("/../.././//../../test-chase.fsldajfl", NULL, CHASE_NONEXISTENT, &result);
assert_se(r == 0);
assert_se(streq(result, "/test-chase.fsldajfl"));
result = mfree(result);
r = chase_symlinks("/../.././//../../etc", "/", CHASE_PREFIX_ROOT, &result);
assert_se(r > 0);
assert_se(streq(result, "/etc"));
result = mfree(result);
r = chase_symlinks("/../.././//../../test-chase.fsldajfl", "/", CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &result);
assert_se(r == 0);
assert_se(streq(result, "/test-chase.fsldajfl"));
result = mfree(result);
r = chase_symlinks("/etc/machine-id/foo", NULL, 0, &result);
assert_se(r == -ENOTDIR);
result = mfree(result);
@ -242,6 +262,7 @@ static void test_readlink_and_make_absolute(void) {
char name2[] = "test-readlink_and_make_absolute/original";
char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
char *r = NULL;
_cleanup_free_ char *pwd = NULL;
assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid(), false) >= 0);
assert_se(touch(name) >= 0);
@ -252,6 +273,8 @@ static void test_readlink_and_make_absolute(void) {
free(r);
assert_se(unlink(name_alias) >= 0);
assert_se(pwd = get_current_dir_name());
assert_se(chdir(tempdir) >= 0);
assert_se(symlink(name2, name_alias) >= 0);
assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
@ -259,6 +282,8 @@ static void test_readlink_and_make_absolute(void) {
free(r);
assert_se(unlink(name_alias) >= 0);
assert_se(chdir(pwd) >= 0);
assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
}