From 22b768d127fbd4b5d87f6017e2afb07febca72f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sat, 27 Apr 2024 21:22:02 +0200 Subject: [PATCH 1/3] basic: add mknodat_label() Add helper for mknodat(2) which creates the destination with the correct security label. --- src/shared/label-util.c | 9 +++++---- src/shared/label-util.h | 6 +++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/shared/label-util.c b/src/shared/label-util.c index 308fbff761..2c482daaf6 100644 --- a/src/shared/label-util.c +++ b/src/shared/label-util.c @@ -81,22 +81,23 @@ int symlink_atomic_full_label(const char *from, const char *to, bool make_relati return mac_smack_fix(to, 0); } -int mknod_label(const char *pathname, mode_t mode, dev_t dev) { +int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev) { int r; + assert(dirfd >= 0 || dirfd == AT_FDCWD); assert(pathname); - r = mac_selinux_create_file_prepare(pathname, mode); + r = mac_selinux_create_file_prepare_at(dirfd, pathname, mode); if (r < 0) return r; - r = RET_NERRNO(mknod(pathname, mode, dev)); + r = RET_NERRNO(mknodat(dirfd, pathname, mode, dev)); mac_selinux_create_file_clear(); if (r < 0) return r; - return mac_smack_fix(pathname, 0); + return mac_smack_fix_full(dirfd, pathname, NULL, 0); } int btrfs_subvol_make_label(const char *path) { diff --git a/src/shared/label-util.h b/src/shared/label-util.h index 7fb98c7656..5a19a4cd43 100644 --- a/src/shared/label-util.h +++ b/src/shared/label-util.h @@ -21,7 +21,11 @@ int symlink_atomic_full_label(const char *from, const char *to, bool make_relati static inline int symlink_atomic_label(const char *from, const char *to) { return symlink_atomic_full_label(from, to, false); } -int mknod_label(const char *pathname, mode_t mode, dev_t dev); + +int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev); +static inline int mknod_label(const char *pathname, mode_t mode, dev_t dev) { + return mknodat_label(AT_FDCWD, pathname, mode, dev); +} int btrfs_subvol_make_label(const char *path); From 4be62f821c1a829c429ca90c7276a795ff1a7ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sat, 27 Apr 2024 21:22:33 +0200 Subject: [PATCH 2/3] basic: add open_mkdir_at_full() Add helper for open_mkdir_at() which accepts xopen flags, e.g. to pass XO_LABEL to create the target with the correct security context. --- src/basic/fs-util.c | 4 ++-- src/basic/fs-util.h | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index b3d5e8a07d..64d309317d 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -1025,7 +1025,7 @@ int parse_cifs_service( return 0; } -int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { +int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode) { _cleanup_close_ int fd = -EBADF, parent_fd = -EBADF; _cleanup_free_ char *fname = NULL, *parent = NULL; int r; @@ -1061,7 +1061,7 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { path = fname; } - fd = xopenat_full(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode); + fd = xopenat_full(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, xopen_flags, mode); if (IN_SET(fd, -ELOOP, -ENOTDIR)) return -EEXIST; if (fd < 0) diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index 58a7d0a745..3e2db95304 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -128,15 +128,18 @@ int posix_fallocate_loop(int fd, uint64_t offset, uint64_t size); int parse_cifs_service(const char *s, char **ret_host, char **ret_service, char **ret_path); -int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode); - -int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created); - typedef enum XOpenFlags { XO_LABEL = 1 << 0, XO_SUBVOLUME = 1 << 1, } XOpenFlags; +int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode); +static inline int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { + return open_mkdir_at_full(dirfd, path, flags, 0, mode); +} + +int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created); + int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode); static inline int xopenat(int dir_fd, const char *path, int open_flags) { return xopenat_full(dir_fd, path, open_flags, 0, 0); From b9a05e860cd645bbbd11e35b60e132e63b44994c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sat, 27 Apr 2024 21:23:11 +0200 Subject: [PATCH 3/3] shared: create inaccessible files with correct security label --- src/shared/dev-setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c index 459e727992..5dbf064e77 100644 --- a/src/shared/dev-setup.c +++ b/src/shared/dev-setup.c @@ -110,7 +110,7 @@ int make_inaccessible_nodes( if (parent_fd < 0) return -errno; - inaccessible_fd = open_mkdir_at(parent_fd, "inaccessible", O_CLOEXEC, 0755); + inaccessible_fd = open_mkdir_at_full(parent_fd, "inaccessible", O_CLOEXEC, XO_LABEL, 0755); if (inaccessible_fd < 0) return inaccessible_fd; @@ -132,7 +132,7 @@ int make_inaccessible_nodes( if (S_ISDIR(inode_type)) r = mkdirat_label(inaccessible_fd, fn, 0000); else - r = RET_NERRNO(mknodat(inaccessible_fd, fn, inode_type | 0000, makedev(0, 0))); + r = mknodat_label(inaccessible_fd, fn, inode_type | 0000, makedev(0, 0)); if (r == -EEXIST) { if (fchmodat(inaccessible_fd, fn, 0000, AT_SYMLINK_NOFOLLOW) < 0) log_debug_errno(errno, "Failed to adjust access mode of existing inode '%s', ignoring: %m", path);