mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
base-filesystem: add new helper base_filesystem_create_fd() that operates on an fd, instead of a path
This also changes the open flags from O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW to O_DIRECTORY|O_CLOEXEC. O_RDONLY is redundant, since O_RDONLY is zero anyway, and O_DIRECTORY pins the acces mode enough: it doesn't allow read()/write() anyway when specified. O_NONBLOCK is also pointless given that O_DIRECTORY is specified, it has no meaning on directories. (It is useful if we don't know much about the inode we are opening, and could be a device node or fifo, but the O_DIRECTORY excludes that case.) O_NOFOLLOW is dropped since there's really no point in blocking out the initial entrypoint being a symlink. Once we pinned the the root of the tree it might make sense to restrict symlink use below it, but for the entrypoint itself it doesn't matter.
This commit is contained in:
@@ -130,13 +130,13 @@ static const BaseFilesystem table[] = {
|
||||
# pragma message "Please add an entry above specifying whether your architecture uses /lib64/, /lib32/, or no such links."
|
||||
#endif
|
||||
|
||||
int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int base_filesystem_create_fd(int fd, const char *root, uid_t uid, gid_t gid) {
|
||||
int r;
|
||||
|
||||
fd = open(root, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to open root file system: %m");
|
||||
assert(fd >= 0);
|
||||
assert(root);
|
||||
|
||||
/* The "root" parameter is decoration only – it's only used as part of log messages */
|
||||
|
||||
for (size_t i = 0; i < ELEMENTSOF(table); i++) {
|
||||
if (faccessat(fd, table[i].dir, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
|
||||
@@ -205,3 +205,13 @@ int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
fd = open(ASSERT_PTR(root), O_DIRECTORY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to open root file system: %m");
|
||||
|
||||
return base_filesystem_create_fd(fd, root, uid, gid);
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int base_filesystem_create_fd(int fd, const char *root, uid_t uid, gid_t gid);
|
||||
int base_filesystem_create(const char *root, uid_t uid, gid_t gid);
|
||||
|
||||
@@ -94,7 +94,7 @@ int switch_root(const char *new_root,
|
||||
/* Do not fail if base_filesystem_create() fails. Not all switch roots are like base_filesystem_create() wants
|
||||
* them to look like. They might even boot, if they are RO and don't have the FS layout. Just ignore the error
|
||||
* and switch_root() nevertheless. */
|
||||
(void) base_filesystem_create(new_root, UID_INVALID, GID_INVALID);
|
||||
(void) base_filesystem_create_fd(new_root_fd, new_root, UID_INVALID, GID_INVALID);
|
||||
|
||||
if (fchdir(new_root_fd) < 0)
|
||||
return log_error_errno(errno, "Failed to change directory to %s: %m", new_root);
|
||||
|
||||
Reference in New Issue
Block a user