diff options
author | gerblesh <101901964+gerblesh@users.noreply.github.com> | 2024-11-14 20:12:40 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2024-11-26 18:47:32 +0100 |
commit | bbec1c87d3bf8d14eeb1ee3b4df973a53cca2e58 (patch) | |
tree | 4fcefea41104f03c3364449d98b63e6d1c1462f6 /src/sysext | |
parent | man: several more assorted fixes (diff) | |
download | systemd-bbec1c87d3bf8d14eeb1ee3b4df973a53cca2e58.tar.xz systemd-bbec1c87d3bf8d14eeb1ee3b4df973a53cca2e58.zip |
sysext: set SELinux context for hierarchies and workdir
Diffstat (limited to 'src/sysext')
-rw-r--r-- | src/sysext/sysext.c | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 0adfab253c..aab1f972a4 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include <errno.h> #include <fcntl.h> #include <getopt.h> #include <linux/loop.h> @@ -45,6 +46,7 @@ #include "process-util.h" #include "rm-rf.h" #include "sort-util.h" +#include "selinux-util.h" #include "string-table.h" #include "string-util.h" #include "terminal-util.h" @@ -899,6 +901,7 @@ static int resolve_mutable_directory( _cleanup_free_ char *path = NULL, *resolved_path = NULL, *dir_name = NULL; const char *root = arg_root, *base = MUTABLE_EXTENSIONS_BASE_DIR; int r; + _cleanup_close_ int atfd = -EBADF; assert(hierarchy); assert(ret_resolved_mutable_directory); @@ -943,6 +946,14 @@ static int resolve_mutable_directory( r = mkdir_p(path_in_root, 0700); if (r < 0) return log_error_errno(r, "Failed to create a directory '%s': %m", path_in_root); + + atfd = open(path_in_root, O_DIRECTORY|O_CLOEXEC); + if (atfd < 0) + return log_error_errno(errno, "Failed to open directory '%s': %m", path_in_root); + + r = mac_selinux_fix_full(atfd, NULL, hierarchy, 0); + if (r < 0) + return log_error_errno(r, "Failed to fix SELinux label for '%s': %m", path_in_root); } r = chase(path, root, CHASE_PREFIX_ROOT, &resolved_path, NULL); @@ -1289,6 +1300,7 @@ static int mount_overlayfs_with_op( int r; const char *top_layer = NULL; + _cleanup_close_ int atfd = -EBADF; assert(op); assert(overlay_path); @@ -1301,10 +1313,28 @@ static int mount_overlayfs_with_op( if (r < 0) return log_error_errno(r, "Failed to make directory '%s': %m", meta_path); + atfd = open(meta_path, O_DIRECTORY|O_CLOEXEC); + if (atfd < 0) + return log_error_errno(errno, "Failed to open directory '%s': %m", meta_path); + + r = mac_selinux_fix_full(atfd, NULL, op->hierarchy, 0); + if (r < 0) + return log_error_errno(r, "Failed to fix SELinux label for '%s': %m", meta_path); + if (op->upper_dir && op->work_dir) { r = mkdir_p(op->work_dir, 0700); if (r < 0) return log_error_errno(r, "Failed to make directory '%s': %m", op->work_dir); + _cleanup_close_ int dfd = -EBADF; + + dfd = open(op->work_dir, O_DIRECTORY|O_CLOEXEC); + if (dfd < 0) + return log_error_errno(errno, "Failed to open directory '%s': %m", op->work_dir); + + r = mac_selinux_fix_full(dfd, NULL, op->hierarchy, 0); + if (r < 0) + return log_error_errno(r, "Failed to fix SELinux label for '%s': %m", op->work_dir); + top_layer = op->upper_dir; } else { assert(!strv_isempty(op->lower_dirs)); @@ -1325,7 +1355,7 @@ static int mount_overlayfs_with_op( return 0; } -static int write_extensions_file(ImageClass image_class, char **extensions, const char *meta_path) { +static int write_extensions_file(ImageClass image_class, char **extensions, const char *meta_path, const char *hierarchy) { _cleanup_free_ char *f = NULL, *buf = NULL; int r; @@ -1343,14 +1373,15 @@ static int write_extensions_file(ImageClass image_class, char **extensions, cons if (!buf) return log_oom(); - r = write_string_file(f, buf, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MKDIR_0755); + const char *hierarchy_path = path_join(hierarchy, image_class_info[image_class].dot_directory_name, image_class_info[image_class].short_identifier_plural); + r = write_string_file_full(AT_FDCWD,f, buf, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL, NULL, hierarchy_path); if (r < 0) return log_error_errno(r, "Failed to write extension meta file '%s': %m", f); return 0; } -static int write_dev_file(ImageClass image_class, const char *meta_path, const char *overlay_path) { +static int write_dev_file(ImageClass image_class, const char *meta_path, const char *overlay_path, const char *hierarchy) { _cleanup_free_ char *f = NULL; struct stat st; int r; @@ -1372,14 +1403,15 @@ static int write_dev_file(ImageClass image_class, const char *meta_path, const c /* Modifying the underlying layers while the overlayfs is mounted is technically undefined, but at * least it won't crash or deadlock, as per the kernel docs about overlayfs: * https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html#changes-to-underlying-filesystems */ - r = write_string_file(f, FORMAT_DEVNUM(st.st_dev), WRITE_STRING_FILE_CREATE); + const char *hierarchy_path = path_join(hierarchy, image_class_info[image_class].dot_directory_name, image_class_info[image_class].short_identifier_plural); + r = write_string_file_full(AT_FDCWD, f, FORMAT_DEVNUM(st.st_dev), WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_LABEL, NULL, hierarchy_path); if (r < 0) return log_error_errno(r, "Failed to write '%s': %m", f); return 0; } -static int write_work_dir_file(ImageClass image_class, const char *meta_path, const char *work_dir) { +static int write_work_dir_file(ImageClass image_class, const char *meta_path, const char *work_dir, const char* hierarchy) { _cleanup_free_ char *escaped_work_dir_in_root = NULL, *f = NULL; char *work_dir_in_root = NULL; int r; @@ -1406,7 +1438,8 @@ static int write_work_dir_file(ImageClass image_class, const char *meta_path, co escaped_work_dir_in_root = cescape(work_dir_in_root); if (!escaped_work_dir_in_root) return log_oom(); - r = write_string_file(f, escaped_work_dir_in_root, WRITE_STRING_FILE_CREATE); + const char *hierarchy_path = path_join(hierarchy, image_class_info[image_class].dot_directory_name, "work_dir"); + r = write_string_file_full(AT_FDCWD, f, escaped_work_dir_in_root, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_LABEL, NULL, hierarchy_path); if (r < 0) return log_error_errno(r, "Failed to write '%s': %m", f); @@ -1418,8 +1451,10 @@ static int store_info_in_meta( char **extensions, const char *meta_path, const char *overlay_path, - const char *work_dir) { - + const char *work_dir, + const char *hierarchy) { + _cleanup_free_ char *f = NULL; + _cleanup_close_ int atfd = -EBADF; int r; assert(extensions); @@ -1427,15 +1462,32 @@ static int store_info_in_meta( assert(overlay_path); /* work_dir may be NULL */ - r = write_extensions_file(image_class, extensions, meta_path); + f = path_join(meta_path, image_class_info[image_class].dot_directory_name); + if (!f) + return log_oom(); + + r = mkdir_p(f, 0755); + if (r < 0) + return r; + + atfd = open(f, O_DIRECTORY|O_CLOEXEC); + if (atfd < 0) + return log_error_errno(errno, "Failed to open directory '%s': %m", f); + + r = mac_selinux_fix_full(atfd, NULL, hierarchy, 0); + + if (r < 0) + return log_error_errno(r, "Failed to fix SELinux label for '%s': %m", hierarchy); + + r = write_extensions_file(image_class, extensions, meta_path, hierarchy); if (r < 0) return r; - r = write_dev_file(image_class, meta_path, overlay_path); + r = write_dev_file(image_class, meta_path, overlay_path, hierarchy); if (r < 0) return r; - r = write_work_dir_file(image_class, meta_path, work_dir); + r = write_work_dir_file(image_class, meta_path, work_dir, hierarchy); if (r < 0) return r; @@ -1501,6 +1553,8 @@ static int merge_hierarchy( assert(overlay_path); assert(workspace_path); + mac_selinux_init(); + r = determine_used_extensions(hierarchy, paths, &used_paths, &extensions_used); if (r < 0) return r; @@ -1528,7 +1582,7 @@ static int merge_hierarchy( if (r < 0) return r; - r = store_info_in_meta(image_class, extensions, meta_path, overlay_path, op->work_dir); + r = store_info_in_meta(image_class, extensions, meta_path, overlay_path, op->work_dir, op->hierarchy); if (r < 0) return r; |