mirror of
https://github.com/systemd/systemd.git
synced 2025-01-28 21:47:38 +03:00
Merge pull request #6140 from keszybz/rm-rf-symlink
Allow symlinks to root to be removed
This commit is contained in:
commit
99a812ad3b
@ -442,8 +442,8 @@ bool path_equal(const char *a, const char *b) {
|
||||
return path_compare(a, b) == 0;
|
||||
}
|
||||
|
||||
bool path_equal_or_files_same(const char *a, const char *b) {
|
||||
return path_equal(a, b) || files_same(a, b) > 0;
|
||||
bool path_equal_or_files_same(const char *a, const char *b, int flags) {
|
||||
return path_equal(a, b) || files_same(a, b, flags) > 0;
|
||||
}
|
||||
|
||||
char* path_join(const char *root, const char *path, const char *rest) {
|
||||
|
@ -46,7 +46,7 @@ char* path_kill_slashes(char *path);
|
||||
char* path_startswith(const char *path, const char *prefix) _pure_;
|
||||
int path_compare(const char *a, const char *b) _pure_;
|
||||
bool path_equal(const char *a, const char *b) _pure_;
|
||||
bool path_equal_or_files_same(const char *a, const char *b);
|
||||
bool path_equal_or_files_same(const char *a, const char *b, int flags);
|
||||
char* path_join(const char *root, const char *path, const char *rest);
|
||||
|
||||
static inline bool path_equal_ptr(const char *a, const char *b) {
|
||||
|
@ -807,7 +807,7 @@ int pid_from_same_root_fs(pid_t pid) {
|
||||
|
||||
root = procfs_file_alloca(pid, "root");
|
||||
|
||||
return files_same(root, "/proc/1/root");
|
||||
return files_same(root, "/proc/1/root", 0);
|
||||
}
|
||||
|
||||
bool is_main_thread(void) {
|
||||
|
@ -182,7 +182,7 @@ int rm_rf(const char *path, RemoveFlags flags) {
|
||||
/* We refuse to clean the root file system with this
|
||||
* call. This is extra paranoia to never cause a really
|
||||
* seriously broken system. */
|
||||
if (path_equal_or_files_same(path, "/")) {
|
||||
if (path_equal_or_files_same(path, "/", AT_SYMLINK_NOFOLLOW)) {
|
||||
log_error("Attempted to remove entire root file system, and we can't allow that.");
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
|
||||
return false;
|
||||
|
||||
if (a->sockaddr.un.sun_path[0]) {
|
||||
if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
|
||||
if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0))
|
||||
return false;
|
||||
} else {
|
||||
if (a->size != b->size)
|
||||
|
@ -169,16 +169,16 @@ int path_is_os_tree(const char *path) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int files_same(const char *filea, const char *fileb) {
|
||||
int files_same(const char *filea, const char *fileb, int flags) {
|
||||
struct stat a, b;
|
||||
|
||||
assert(filea);
|
||||
assert(fileb);
|
||||
|
||||
if (stat(filea, &a) < 0)
|
||||
if (fstatat(AT_FDCWD, filea, &a, flags) < 0)
|
||||
return -errno;
|
||||
|
||||
if (stat(fileb, &b) < 0)
|
||||
if (fstatat(AT_FDCWD, fileb, &b, flags) < 0)
|
||||
return -errno;
|
||||
|
||||
return a.st_dev == b.st_dev &&
|
||||
|
@ -49,7 +49,7 @@ int null_or_empty_fd(int fd);
|
||||
int path_is_read_only_fs(const char *path);
|
||||
int path_is_os_tree(const char *path);
|
||||
|
||||
int files_same(const char *filea, const char *fileb);
|
||||
int files_same(const char *filea, const char *fileb, int flags);
|
||||
|
||||
/* The .f_type field of struct statfs is really weird defined on
|
||||
* different archs. Let's give its type a name. */
|
||||
|
@ -541,7 +541,7 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
|
||||
if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = files_same(userns_fd_path, "/proc/self/ns/user");
|
||||
r = files_same(userns_fd_path, "/proc/self/ns/user", 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r)
|
||||
|
@ -574,7 +574,7 @@ int running_in_chroot(void) {
|
||||
if (getenv_bool("SYSTEMD_IGNORE_CHROOT") > 0)
|
||||
return 0;
|
||||
|
||||
ret = files_same("/proc/1/root", "/");
|
||||
ret = files_same("/proc/1/root", "/", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -2528,7 +2528,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
else
|
||||
LIST_FOREACH(port, p, s->ports)
|
||||
if (p->type == SOCKET_FIFO &&
|
||||
path_equal_or_files_same(p->path, value+skip)) {
|
||||
path_equal_or_files_same(p->path, value+skip, 0)) {
|
||||
socket_port_take_fd(p, fds, fd);
|
||||
break;
|
||||
}
|
||||
@ -2542,7 +2542,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
else
|
||||
LIST_FOREACH(port, p, s->ports)
|
||||
if (p->type == SOCKET_SPECIAL &&
|
||||
path_equal_or_files_same(p->path, value+skip)) {
|
||||
path_equal_or_files_same(p->path, value+skip, 0)) {
|
||||
socket_port_take_fd(p, fds, fd);
|
||||
break;
|
||||
}
|
||||
@ -2596,7 +2596,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
else
|
||||
LIST_FOREACH(port, p, s->ports)
|
||||
if (p->type == SOCKET_USB_FUNCTION &&
|
||||
path_equal_or_files_same(p->path, value+skip)) {
|
||||
path_equal_or_files_same(p->path, value+skip, 0)) {
|
||||
socket_port_take_fd(p, fds, fd);
|
||||
break;
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ static bool chroot_symlinks_same(const char *root, const char *wd, const char *a
|
||||
|
||||
a = strjoina(path_is_absolute(a) ? root : wd, "/", a);
|
||||
b = strjoina(path_is_absolute(b) ? root : wd, "/", b);
|
||||
return path_equal_or_files_same(a, b);
|
||||
return path_equal_or_files_same(a, b, 0);
|
||||
}
|
||||
|
||||
static int create_symlink(
|
||||
|
@ -5654,7 +5654,7 @@ static int switch_root(int argc, char *argv[], void *userdata) {
|
||||
|
||||
/* If the passed init is actually the same as the
|
||||
* systemd binary, then let's suppress it. */
|
||||
if (files_same(root_init_path, root_systemd_path) > 0)
|
||||
if (files_same(root_init_path, root_systemd_path, 0) > 0)
|
||||
init = NULL;
|
||||
}
|
||||
|
||||
|
@ -118,23 +118,33 @@ static void test_path_equal_root(void) {
|
||||
|
||||
/* Make sure that files_same works as expected. */
|
||||
|
||||
assert_se(files_same("/", "/") > 0);
|
||||
assert_se(files_same("/", "//") > 0);
|
||||
assert_se(files_same("/", "/", 0) > 0);
|
||||
assert_se(files_same("/", "/", AT_SYMLINK_NOFOLLOW) > 0);
|
||||
assert_se(files_same("/", "//", 0) > 0);
|
||||
assert_se(files_same("/", "//", AT_SYMLINK_NOFOLLOW) > 0);
|
||||
|
||||
assert_se(files_same("/", "/./") > 0);
|
||||
assert_se(files_same("/", "/../") > 0);
|
||||
assert_se(files_same("/", "/./", 0) > 0);
|
||||
assert_se(files_same("/", "/./", AT_SYMLINK_NOFOLLOW) > 0);
|
||||
assert_se(files_same("/", "/../", 0) > 0);
|
||||
assert_se(files_same("/", "/../", AT_SYMLINK_NOFOLLOW) > 0);
|
||||
|
||||
assert_se(files_same("/", "/.../") == -ENOENT);
|
||||
assert_se(files_same("/", "/.../", 0) == -ENOENT);
|
||||
assert_se(files_same("/", "/.../", AT_SYMLINK_NOFOLLOW) == -ENOENT);
|
||||
|
||||
/* The same for path_equal_or_files_same. */
|
||||
|
||||
assert_se(path_equal_or_files_same("/", "/"));
|
||||
assert_se(path_equal_or_files_same("/", "//"));
|
||||
assert_se(path_equal_or_files_same("/", "/", 0));
|
||||
assert_se(path_equal_or_files_same("/", "/", AT_SYMLINK_NOFOLLOW));
|
||||
assert_se(path_equal_or_files_same("/", "//", 0));
|
||||
assert_se(path_equal_or_files_same("/", "//", AT_SYMLINK_NOFOLLOW));
|
||||
|
||||
assert_se(path_equal_or_files_same("/", "/./"));
|
||||
assert_se(path_equal_or_files_same("/", "/../"));
|
||||
assert_se(path_equal_or_files_same("/", "/./", 0));
|
||||
assert_se(path_equal_or_files_same("/", "/./", AT_SYMLINK_NOFOLLOW));
|
||||
assert_se(path_equal_or_files_same("/", "/../", 0));
|
||||
assert_se(path_equal_or_files_same("/", "/../", AT_SYMLINK_NOFOLLOW));
|
||||
|
||||
assert_se(!path_equal_or_files_same("/", "/.../"));
|
||||
assert_se(!path_equal_or_files_same("/", "/.../", 0));
|
||||
assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW));
|
||||
}
|
||||
|
||||
static void test_find_binary(const char *self) {
|
||||
|
@ -38,8 +38,10 @@ static void test_files_same(void) {
|
||||
assert_se(fd >= 0);
|
||||
assert_se(symlink(name, name_alias) >= 0);
|
||||
|
||||
assert_se(files_same(name, name));
|
||||
assert_se(files_same(name, name_alias));
|
||||
assert_se(files_same(name, name, 0));
|
||||
assert_se(files_same(name, name, AT_SYMLINK_NOFOLLOW));
|
||||
assert_se(files_same(name, name_alias, 0));
|
||||
assert_se(!files_same(name, name_alias, AT_SYMLINK_NOFOLLOW));
|
||||
|
||||
unlink(name);
|
||||
unlink(name_alias);
|
||||
|
Loading…
x
Reference in New Issue
Block a user