summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgerblesh <101901964+gerblesh@users.noreply.github.com>2024-11-14 20:12:40 +0100
committerLuca Boccassi <luca.boccassi@gmail.com>2024-11-26 18:47:32 +0100
commitbbec1c87d3bf8d14eeb1ee3b4df973a53cca2e58 (patch)
tree4fcefea41104f03c3364449d98b63e6d1c1462f6
parentman: several more assorted fixes (diff)
downloadsystemd-bbec1c87d3bf8d14eeb1ee3b4df973a53cca2e58.tar.xz
systemd-bbec1c87d3bf8d14eeb1ee3b4df973a53cca2e58.zip
sysext: set SELinux context for hierarchies and workdir
-rw-r--r--src/basic/fileio.c6
-rw-r--r--src/basic/fileio.h7
-rw-r--r--src/sysext/sysext.c78
-rw-r--r--src/update-done/update-done.c2
4 files changed, 75 insertions, 18 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index aa1657c118..52a29e2f7b 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -289,7 +289,8 @@ int write_string_file_full(
const char *fn,
const char *line,
WriteStringFileFlags flags,
- const struct timespec *ts) {
+ const struct timespec *ts,
+ const char *label_fn) {
bool call_label_ops_post = false, made_file = false;
_cleanup_fclose_ FILE *f = NULL;
@@ -321,7 +322,8 @@ int write_string_file_full(
mode_t mode = write_string_file_flags_to_mode(flags);
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)
goto fail;
diff --git a/src/basic/fileio.h b/src/basic/fileio.h
index 8f54491c12..08017f8270 100644
--- a/src/basic/fileio.h
+++ b/src/basic/fileio.h
@@ -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) {
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) {
- 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) {
- 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);
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;
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index 277d2860b9..fdfbb7b52e 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -29,7 +29,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
timespec_load_nsec(ts)) < 0)
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)
log_debug_errno(r, "Cannot create \"%s\", file system is read-only.", path);
else if (r < 0)