]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/tmpfiles/tmpfiles.c
Merge pull request #30480 from keszybz/kernel-install-more-paths
[thirdparty/systemd.git] / src / tmpfiles / tmpfiles.c
index e4854f31b5ddb724e8691bd853932939852fba09..ec6d8dcfa164d994bbe046dd0d0cd74719268f39 100644 (file)
@@ -1257,60 +1257,47 @@ static int parse_acls_from_arg(Item *item) {
 #if HAVE_ACL
 static int parse_acl_cond_exec(
                 const char *path,
-                acl_t access, /* could be empty (NULL) */
-                acl_t cond_exec,
                 const struct stat *st,
+                acl_t cond_exec,
+                acl_t access, /* could be empty (NULL) */
                 bool append,
                 acl_t *ret) {
 
-        _cleanup_(acl_freep) acl_t parsed = NULL;
         acl_entry_t entry;
         acl_permset_t permset;
         bool has_exec;
         int r;
 
         assert(path);
-        assert(ret);
         assert(st);
+        assert(cond_exec);
+        assert(ret);
 
-        parsed = access ? acl_dup(access) : acl_init(0);
-        if (!parsed)
-                return -errno;
-
-        /* Since we substitute 'X' with 'x' in parse_acl(), we just need to copy the entries over
-         * for directories */
-        if (S_ISDIR(st->st_mode)) {
-                for (r = acl_get_entry(cond_exec, ACL_FIRST_ENTRY, &entry);
-                     r > 0;
-                     r = acl_get_entry(cond_exec, ACL_NEXT_ENTRY, &entry)) {
-
-                        acl_entry_t parsed_entry;
-
-                        if (acl_create_entry(&parsed, &parsed_entry) < 0)
-                                return -errno;
-
-                        if (acl_copy_entry(parsed_entry, entry) < 0)
-                                return -errno;
-                }
-                if (r < 0)
-                        return -errno;
-
-                goto finish;
-        }
-
-        has_exec = st->st_mode & S_IXUSR;
-
-        if (!has_exec && append) {
+        if (!S_ISDIR(st->st_mode)) {
                 _cleanup_(acl_freep) acl_t old = NULL;
 
                 old = acl_get_file(path, ACL_TYPE_ACCESS);
                 if (!old)
                         return -errno;
 
+                has_exec = false;
+
                 for (r = acl_get_entry(old, ACL_FIRST_ENTRY, &entry);
                      r > 0;
                      r = acl_get_entry(old, ACL_NEXT_ENTRY, &entry)) {
 
+                        acl_tag_t tag;
+
+                        if (acl_get_tag_type(entry, &tag) < 0)
+                                return -errno;
+
+                        if (tag == ACL_MASK)
+                                continue;
+
+                        /* If not appending, skip ACL definitions */
+                        if (!append && IN_SET(tag, ACL_USER, ACL_GROUP))
+                                continue;
+
                         if (acl_get_permset(entry, &permset) < 0)
                                 return -errno;
 
@@ -1324,28 +1311,33 @@ static int parse_acl_cond_exec(
                 }
                 if (r < 0)
                         return -errno;
-        }
 
-        /* Check if we're about to set the execute bit in acl_access */
-        if (!has_exec && access) {
-                for (r = acl_get_entry(access, ACL_FIRST_ENTRY, &entry);
-                     r > 0;
-                     r = acl_get_entry(access, ACL_NEXT_ENTRY, &entry)) {
+                /* Check if we're about to set the execute bit in acl_access */
+                if (!has_exec && access) {
+                        for (r = acl_get_entry(access, ACL_FIRST_ENTRY, &entry);
+                             r > 0;
+                             r = acl_get_entry(access, ACL_NEXT_ENTRY, &entry)) {
 
-                        if (acl_get_permset(entry, &permset) < 0)
-                                return -errno;
+                                if (acl_get_permset(entry, &permset) < 0)
+                                        return -errno;
 
-                        r = acl_get_perm(permset, ACL_EXECUTE);
+                                r = acl_get_perm(permset, ACL_EXECUTE);
+                                if (r < 0)
+                                        return -errno;
+                                if (r > 0) {
+                                        has_exec = true;
+                                        break;
+                                }
+                        }
                         if (r < 0)
                                 return -errno;
-                        if (r > 0) {
-                                has_exec = true;
-                                break;
-                        }
                 }
-                if (r < 0)
-                        return -errno;
-        }
+        } else
+                has_exec = true;
+
+        _cleanup_(acl_freep) acl_t parsed = access ? acl_dup(access) : acl_init(0);
+        if (!parsed)
+                return -errno;
 
         for (r = acl_get_entry(cond_exec, ACL_FIRST_ENTRY, &entry);
              r > 0;
@@ -1359,6 +1351,7 @@ static int parse_acl_cond_exec(
                 if (acl_copy_entry(parsed_entry, entry) < 0)
                         return -errno;
 
+                /* We substituted 'X' with 'x' in parse_acl(), so drop execute bit here if not applicable. */
                 if (!has_exec) {
                         if (acl_get_permset(parsed_entry, &permset) < 0)
                                 return -errno;
@@ -1370,7 +1363,6 @@ static int parse_acl_cond_exec(
         if (r < 0)
                 return -errno;
 
-finish:
         if (!append) { /* want_mask = true */
                 r = calc_acl_mask_if_needed(&parsed);
                 if (r < 0)
@@ -1475,10 +1467,9 @@ static int fd_set_acls(
         }
 
         if (item->acl_access_exec) {
-                r = parse_acl_cond_exec(FORMAT_PROC_FD_PATH(fd),
-                                        item->acl_access,
+                r = parse_acl_cond_exec(FORMAT_PROC_FD_PATH(fd), st,
                                         item->acl_access_exec,
-                                        st,
+                                        item->acl_access,
                                         item->append_or_force,
                                         &access_with_exec_parsed);
                 if (r < 0)
@@ -3648,8 +3639,7 @@ static int parse_line(
                         &mode,
                         &user,
                         &group,
-                        &age,
-                        NULL);
+                        &age);
         if (r < 0) {
                 if (IN_SET(r, -EINVAL, -EBADSLT))
                         /* invalid quoting and such or an unknown specifier */
@@ -4626,7 +4616,8 @@ static int run(int argc, char *argv[]) {
                                 DISSECT_IMAGE_VALIDATE_OS |
                                 DISSECT_IMAGE_RELAX_VAR_CHECK |
                                 DISSECT_IMAGE_FSCK |
-                                DISSECT_IMAGE_GROWFS,
+                                DISSECT_IMAGE_GROWFS |
+                                DISSECT_IMAGE_ALLOW_USERSPACE_VERITY,
                                 &mounted_dir,
                                 /* ret_dir_fd= */ NULL,
                                 &loop_device);