Compare commits

..

2 Commits

Author SHA1 Message Date
Dan Streetman 151ed27f2d
Merge 413f6e0f56 into bbec1c87d3 2024-11-26 20:14:31 -08:00
gerblesh bbec1c87d3 sysext: set SELinux context for hierarchies and workdir 2024-11-26 17:47:32 +00:00
4 changed files with 75 additions and 18 deletions

View File

@ -289,7 +289,8 @@ int write_string_file_full(
const char *fn, const char *fn,
const char *line, const char *line,
WriteStringFileFlags flags, WriteStringFileFlags flags,
const struct timespec *ts) { const struct timespec *ts,
const char *label_fn) {
bool call_label_ops_post = false, made_file = false; bool call_label_ops_post = false, made_file = false;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
@ -321,7 +322,8 @@ int write_string_file_full(
mode_t mode = write_string_file_flags_to_mode(flags); mode_t mode = write_string_file_flags_to_mode(flags);
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) { if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
r = label_ops_pre(dir_fd, fn, mode); const char *lookup = label_fn ? label_fn : fn;
r = label_ops_pre(dir_fd, lookup, mode);
if (r < 0) if (r < 0)
goto fail; goto fail;

View File

@ -51,12 +51,13 @@ int write_string_stream_full(FILE *f, const char *line, WriteStringFileFlags fla
static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) { static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) {
return write_string_stream_full(f, line, flags, /* ts= */ NULL); return write_string_stream_full(f, line, flags, /* ts= */ NULL);
} }
int write_string_file_full(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts);
int write_string_file_full(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts, const char *label_fn);
static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) { static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
return write_string_file_full(AT_FDCWD, fn, line, flags, /* ts= */ NULL); return write_string_file_full(AT_FDCWD, fn, line, flags, /* ts= */ NULL, /*label_fn=*/ NULL);
} }
static inline int write_string_file_at(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags) { static inline int write_string_file_at(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags) {
return write_string_file_full(dir_fd, fn, line, flags, /* ts= */ NULL); return write_string_file_full(dir_fd, fn, line, flags, /* ts= */ NULL, /*label_fn=*/ NULL);
} }
int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4);

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <getopt.h> #include <getopt.h>
#include <linux/loop.h> #include <linux/loop.h>
@ -45,6 +46,7 @@
#include "process-util.h" #include "process-util.h"
#include "rm-rf.h" #include "rm-rf.h"
#include "sort-util.h" #include "sort-util.h"
#include "selinux-util.h"
#include "string-table.h" #include "string-table.h"
#include "string-util.h" #include "string-util.h"
#include "terminal-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; _cleanup_free_ char *path = NULL, *resolved_path = NULL, *dir_name = NULL;
const char *root = arg_root, *base = MUTABLE_EXTENSIONS_BASE_DIR; const char *root = arg_root, *base = MUTABLE_EXTENSIONS_BASE_DIR;
int r; int r;
_cleanup_close_ int atfd = -EBADF;
assert(hierarchy); assert(hierarchy);
assert(ret_resolved_mutable_directory); assert(ret_resolved_mutable_directory);
@ -943,6 +946,14 @@ static int resolve_mutable_directory(
r = mkdir_p(path_in_root, 0700); r = mkdir_p(path_in_root, 0700);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to create a directory '%s': %m", path_in_root); 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); r = chase(path, root, CHASE_PREFIX_ROOT, &resolved_path, NULL);
@ -1289,6 +1300,7 @@ static int mount_overlayfs_with_op(
int r; int r;
const char *top_layer = NULL; const char *top_layer = NULL;
_cleanup_close_ int atfd = -EBADF;
assert(op); assert(op);
assert(overlay_path); assert(overlay_path);
@ -1301,10 +1313,28 @@ static int mount_overlayfs_with_op(
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to make directory '%s': %m", meta_path); 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) { if (op->upper_dir && op->work_dir) {
r = mkdir_p(op->work_dir, 0700); r = mkdir_p(op->work_dir, 0700);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to make directory '%s': %m", op->work_dir); 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; top_layer = op->upper_dir;
} else { } else {
assert(!strv_isempty(op->lower_dirs)); assert(!strv_isempty(op->lower_dirs));
@ -1325,7 +1355,7 @@ static int mount_overlayfs_with_op(
return 0; 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; _cleanup_free_ char *f = NULL, *buf = NULL;
int r; int r;
@ -1343,14 +1373,15 @@ static int write_extensions_file(ImageClass image_class, char **extensions, cons
if (!buf) if (!buf)
return log_oom(); 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) if (r < 0)
return log_error_errno(r, "Failed to write extension meta file '%s': %m", f); return log_error_errno(r, "Failed to write extension meta file '%s': %m", f);
return 0; 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; _cleanup_free_ char *f = NULL;
struct stat st; struct stat st;
int r; 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 /* 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: * 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 */ * 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) if (r < 0)
return log_error_errno(r, "Failed to write '%s': %m", f); return log_error_errno(r, "Failed to write '%s': %m", f);
return 0; 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; _cleanup_free_ char *escaped_work_dir_in_root = NULL, *f = NULL;
char *work_dir_in_root = NULL; char *work_dir_in_root = NULL;
int r; 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); escaped_work_dir_in_root = cescape(work_dir_in_root);
if (!escaped_work_dir_in_root) if (!escaped_work_dir_in_root)
return log_oom(); 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) if (r < 0)
return log_error_errno(r, "Failed to write '%s': %m", f); return log_error_errno(r, "Failed to write '%s': %m", f);
@ -1418,8 +1451,10 @@ static int store_info_in_meta(
char **extensions, char **extensions,
const char *meta_path, const char *meta_path,
const char *overlay_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; int r;
assert(extensions); assert(extensions);
@ -1427,15 +1462,32 @@ static int store_info_in_meta(
assert(overlay_path); assert(overlay_path);
/* work_dir may be NULL */ /* 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) if (r < 0)
return r; return r;
r = write_dev_file(image_class, meta_path, overlay_path); 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) if (r < 0)
return r; return r;
r = write_work_dir_file(image_class, meta_path, work_dir); 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, hierarchy);
if (r < 0) if (r < 0)
return r; return r;
@ -1501,6 +1553,8 @@ static int merge_hierarchy(
assert(overlay_path); assert(overlay_path);
assert(workspace_path); assert(workspace_path);
mac_selinux_init();
r = determine_used_extensions(hierarchy, paths, &used_paths, &extensions_used); r = determine_used_extensions(hierarchy, paths, &used_paths, &extensions_used);
if (r < 0) if (r < 0)
return r; return r;
@ -1528,7 +1582,7 @@ static int merge_hierarchy(
if (r < 0) if (r < 0)
return r; 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) if (r < 0)
return r; return r;

View File

@ -29,7 +29,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
timespec_load_nsec(ts)) < 0) timespec_load_nsec(ts)) < 0)
return log_oom(); return log_oom();
r = write_string_file_full(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL, ts); r = write_string_file_full(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL, ts, NULL);
if (r == -EROFS) if (r == -EROFS)
log_debug_errno(r, "Cannot create \"%s\", file system is read-only.", path); log_debug_errno(r, "Cannot create \"%s\", file system is read-only.", path);
else if (r < 0) else if (r < 0)