From 29a438e764cbfdddd43e175490e2d8c8eb21b79e Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Tue, 5 Mar 2024 22:25:44 +0800 Subject: [PATCH] tmpfiles: do 'X' bit check in an ACL-aware manner Follow-up for 26d98cdd78cb5283f5771bd5866997acc494b067 I.e. stat() cannot be used here. Also, before this commit, the 'X' is only applied if the owner has execute bit set. Now it takes group and other into consideration too. setfacl(1) also has the same behavior. --- src/tmpfiles/tmpfiles.c | 46 +++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 0dd890958c6..ede5ca8a964 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -1275,33 +1275,43 @@ static int parse_acl_cond_exec( assert(ret); if (!S_ISDIR(st->st_mode)) { - has_exec = st->st_mode & S_IXUSR; + _cleanup_(acl_freep) acl_t old = NULL; - if (!has_exec && append) { - _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)) { - old = acl_get_file(path, ACL_TYPE_ACCESS); - if (!old) + acl_tag_t tag; + + if (acl_get_tag_type(entry, &tag) < 0) return -errno; - for (r = acl_get_entry(old, ACL_FIRST_ENTRY, &entry); - r > 0; - r = acl_get_entry(old, ACL_NEXT_ENTRY, &entry)) { + if (tag == ACL_MASK) + continue; - if (acl_get_permset(entry, &permset) < 0) - return -errno; + /* If not appending, skip ACL definitions */ + if (!append && IN_SET(tag, ACL_USER, ACL_GROUP)) + continue; - r = acl_get_perm(permset, ACL_EXECUTE); - if (r < 0) - return -errno; - if (r > 0) { - has_exec = true; - break; - } - } + if (acl_get_permset(entry, &permset) < 0) + return -errno; + + r = acl_get_perm(permset, ACL_EXECUTE); if (r < 0) return -errno; + if (r > 0) { + has_exec = true; + break; + } } + if (r < 0) + return -errno; /* Check if we're about to set the execute bit in acl_access */ if (!has_exec && access) { -- 2.47.3