diff --git a/lustre/utils/l_getsepol.c b/lustre/utils/l_getsepol.c index 01df684e5d..4936801ee0 100644 --- a/lustre/utils/l_getsepol.c +++ b/lustre/utils/l_getsepol.c @@ -339,7 +339,7 @@ int main(int argc, char **argv) goto out; } - /* Max version of loaded policy */ + /* Policy format version reported by the running kernel */ policyver = security_policyvers(); if (policyver < 0) { errlog("unknown policy version: %s\n", strerror(errno)); @@ -347,24 +347,52 @@ int main(int argc, char **argv) goto out; } - while (policymtime == 0) { - /* Path of binary policy file */ - snprintf(pol_bin_path, sizeof(pol_bin_path), "%s.%d", - selinux_binary_policy_path(), policyver); - - /* Stat binary policy file */ - if (stat(pol_bin_path, &st)) { - if (policyver > 0) { - policyver--; - } else { - errlog("can't stat %s.*: %s\n", - selinux_binary_policy_path(), - strerror(errno)); - rc = -errno; - goto out; + /* Find the on-disk policy.N file for both mtime (change detection) + * and hashing. Always using the on-disk file ensures all l_getsepol + * clients in a nodemap produce an identical hash string. + * Note: /sys/fs/selinux/policy also exports the loaded policy binary, + * but it is a re-serialization of the kernel's in-memory policydb, + * not a verbatim copy of the file, so its hash may differ. + * + * Search downward from security_policyvers() first (traditional + * path), then downward from policyvers+10 to handle distros where + * the on-disk binary version exceeds what security_policyvers() + * reports (e.g. RHEL 10.1: policy.35 on disk but + * security_policyvers()=33). + */ + { + const char *policy_path = selinux_binary_policy_path(); + int v; + + for (v = policyver; v >= 0; v--) { + snprintf(pol_bin_path, sizeof(pol_bin_path), "%s.%d", + policy_path, v); + if (stat(pol_bin_path, &st) == 0) { + policymtime = st.st_mtime; + policyver = v; + break; } - } else { - policymtime = st.st_mtime; + } + + if (policymtime == 0) { + int maxver = policyver + 10; + + for (v = maxver; v > policyver; v--) { + snprintf(pol_bin_path, sizeof(pol_bin_path), + "%s.%d", policy_path, v); + if (stat(pol_bin_path, &st) == 0) { + policymtime = st.st_mtime; + policyver = v; + break; + } + } + } + + if (policymtime == 0) { + errlog("can't stat %s.*: %s\n", + policy_path, strerror(errno)); + rc = -errno; + goto out; } }