summaryrefslogtreecommitdiffstats
path: root/src/sysext
diff options
context:
space:
mode:
authorKrzesimir Nowak <knowak@microsoft.com>2024-03-28 15:21:08 +0100
committerKrzesimir Nowak <knowak@microsoft.com>2024-04-19 07:18:34 +0200
commite30623b79dc75386ea62668b41669550388bf680 (patch)
treea4fd91fc85e9dca55a4e63e117dc0a178b88470a /src/sysext
parenttest: Add sysext test-cases for checking mode preservation (diff)
downloadsystemd-e30623b79dc75386ea62668b41669550388bf680.tar.xz
systemd-e30623b79dc75386ea62668b41669550388bf680.zip
sysext: Check if preexisting mutable directory has a valid mode
Preexisting mutable directory is likely set by the admin, so we expect it to be set up properly instead of changing the mode of the directory behind admin's back.
Diffstat (limited to 'src/sysext')
-rw-r--r--src/sysext/sysext.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index 07a9619bd1..47ba78ab3a 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -768,8 +768,37 @@ static int resolve_hierarchy(const char *hierarchy, char **ret_resolved_hierarch
return 0;
}
+static int mutable_directory_mode_matches_hierarchy(
+ const char *root_or_null,
+ const char *path,
+ mode_t hierarchy_mode) {
+
+ _cleanup_free_ char *path_in_root = NULL;
+ struct stat st;
+ mode_t actual_mode;
+
+ assert(path);
+
+ path_in_root = path_join(root_or_null, path);
+ if (!path_in_root)
+ return log_oom();
+
+ if (stat(path_in_root, &st) < 0) {
+ if (errno == ENOENT)
+ return 0;
+ return log_error_errno(errno, "Failed to stat mutable directory '%s': %m", path_in_root);
+ }
+
+ actual_mode = st.st_mode & 0777;
+ if (actual_mode != hierarchy_mode)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Mutable directory '%s' has mode %04o, ought to have mode %04o", path_in_root, actual_mode, hierarchy_mode);
+
+ return 0;
+}
+
static int resolve_mutable_directory(
const char *hierarchy,
+ mode_t hierarchy_mode,
const char *workspace,
char **ret_resolved_mutable_directory) {
@@ -801,6 +830,15 @@ static int resolve_mutable_directory(
if (!path)
return log_oom();
+ if (IN_SET(arg_mutable, MUTABLE_YES, MUTABLE_AUTO)) {
+ /* If there already is a mutable directory, check if its mode matches hierarchy. Merged
+ * hierarchy will have the same mode as the mutable directory, so we want no surprising mode
+ * changes here. */
+ r = mutable_directory_mode_matches_hierarchy(root, path, hierarchy_mode);
+ if (r < 0)
+ return r;
+ }
+
if (IN_SET(arg_mutable, MUTABLE_YES, MUTABLE_EPHEMERAL, MUTABLE_EPHEMERAL_IMPORT)) {
_cleanup_free_ char *path_in_root = NULL;
@@ -847,7 +885,7 @@ static int overlayfs_paths_new(const char *hierarchy, const char *workspace_path
} else
hierarchy_mode = 0755;
- r = resolve_mutable_directory(hierarchy, workspace_path, &resolved_mutable_directory);
+ r = resolve_mutable_directory(hierarchy, hierarchy_mode, workspace_path, &resolved_mutable_directory);
if (r < 0)
return r;