core: centralize RestrictFileSystemAccess= checks

Centralize the checks for RestrictFileSystemAccess= requirements.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2026-08-31 23:33:39 +02:00
parent c35f061634
commit 73e093d16d
4 changed files with 41 additions and 37 deletions
+33 -21
View File
@@ -81,7 +81,7 @@ assert_cc(sizeof_field(typeof_field(struct restrict_fsaccess_bpf, bss[0]), initr
[RESTRICT_FILESYSTEM_ACCESS_LINK_BPF_GUARD] = (obj)->links.restrict_fsaccess_bpf_guard, \
}
bool dm_verity_require_signatures(void) {
static bool dm_verity_require_signatures(void) {
int r;
r = read_boolean_file("/sys/module/dm_verity/parameters/require_signatures");
@@ -94,6 +94,35 @@ bool dm_verity_require_signatures(void) {
return r > 0;
}
/* The kernel-side prerequisites of the policy, shared with test-bpf-restrict-fsaccess. */
int bpf_restrict_fsaccess_check_prerequisites(void) {
int r;
r = dlopen_bpf(LOG_ERR);
if (r < 0)
return r;
r = lsm_supported("bpf");
if (r == -ENOPKG)
return log_error_errno(r, "bpf-restrict-fsaccess: securityfs not mounted, BPF LSM not available.");
if (r < 0)
return log_error_errno(r, "bpf-restrict-fsaccess: Can't determine whether the BPF LSM module is "
"used: %m");
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"bpf-restrict-fsaccess: BPF LSM hook not enabled in the kernel, not supported.");
log_debug("bpf-restrict-fsaccess: BPF LSM: supported.");
if (!dm_verity_require_signatures())
return log_error_errno(SYNTHETIC_ERRNO(ENOKEY),
"bpf-restrict-fsaccess: dm-verity require_signatures is not enabled. "
"RestrictFileSystemAccess= requires the kernel to enforce dm-verity signatures. "
"Set dm_verity.require_signatures=1 on the kernel command line.");
log_debug("bpf-restrict-fsaccess: dm-verity require_signatures: enabled.");
return 0;
}
static int get_root_s_dev(uint32_t *ret) {
struct stat st;
@@ -416,27 +445,10 @@ int bpf_restrict_fsaccess_setup(Manager *m) {
return 0;
}
/* Fresh setup: verify BPF LSM is available */
r = dlopen_bpf(LOG_WARNING);
r = bpf_restrict_fsaccess_check_prerequisites();
if (r < 0)
return r;
r = lsm_supported("bpf");
if (r == -ENOPKG)
return log_warning_errno(r, "bpf-restrict-fsaccess: securityfs not mounted, BPF LSM not available.");
if (r < 0)
return log_warning_errno(r, "bpf-restrict-fsaccess: Can't determine whether the BPF LSM module is used: %m");
if (r == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"bpf-restrict-fsaccess: BPF LSM hook not enabled in the kernel, not supported.");
/* Require dm-verity signature enforcement */
if (!dm_verity_require_signatures())
return log_error_errno(SYNTHETIC_ERRNO(ENOKEY),
"bpf-restrict-fsaccess: dm-verity require_signatures is not enabled. "
"RestrictFileSystemAccess= requires the kernel to enforce dm-verity signatures. "
"Set dm_verity.require_signatures=1 on the kernel command line.");
r = bpf_restrict_fsaccess_prepare(&obj);
if (r < 0)
return r;
@@ -554,8 +566,8 @@ int bpf_restrict_fsaccess_serialize(Manager *m, FILE *f, FDSet *fds) {
#else /* ! BPF_FRAMEWORK || ! HAVE_LSM_INTEGRITY_TYPE */
bool dm_verity_require_signatures(void) {
return false;
int bpf_restrict_fsaccess_check_prerequisites(void) {
return -EOPNOTSUPP;
}
int bpf_restrict_fsaccess_setup(Manager *m) {
+1 -1
View File
@@ -33,7 +33,7 @@ enum {
extern const char* const restrict_fsaccess_link_names[_RESTRICT_FILESYSTEM_ACCESS_LINK_MAX];
bool dm_verity_require_signatures(void);
int bpf_restrict_fsaccess_check_prerequisites(void);
int bpf_restrict_fsaccess_setup(Manager *m);
int bpf_restrict_fsaccess_prepare(struct restrict_fsaccess_bpf **ret);
int bpf_restrict_fsaccess_populate_guard(struct restrict_fsaccess_bpf *obj);
+5 -12
View File
@@ -7,7 +7,8 @@
* test-bpf-restrict-fsaccess attach — Load, attach, print IDs, then block.
* Kill the process to detach (synchronous
* via bpf_link_put_direct on last FD close).
* test-bpf-restrict-fsaccess check — Check BPF LSM + require_signatures preconditions
* test-bpf-restrict-fsaccess check — Run PID 1's prerequisite checks (BPF LSM,
* require_signatures)
* test-bpf-restrict-fsaccess mmap-exec PATH — Attempt PROT_READ|PROT_EXEC mmap of PATH
* test-bpf-restrict-fsaccess anon-mmap-exec — Attempt anonymous PROT_READ|PROT_EXEC mmap
* test-bpf-restrict-fsaccess mprotect-exec PATH — mmap PATH PROT_READ, then mprotect to PROT_EXEC
@@ -34,7 +35,6 @@
#include "errno-util.h"
#include "fd-util.h"
#include "log.h"
#include "lsm-util.h"
#include "string-util.h"
#include "tests.h"
@@ -241,15 +241,12 @@ static int do_attach(void) {
static int do_check(void) {
int r;
r = dlopen_bpf(LOG_WARNING);
r = bpf_restrict_fsaccess_check_prerequisites();
if (r < 0)
return r;
r = lsm_supported("bpf");
if (r <= 0)
return log_error_errno(r < 0 ? r : EOPNOTSUPP, "BPF LSM is not available: %m");
log_info("BPF LSM: supported");
/* Last: linking attaches bprm_check for an instant with an empty trust map, during which every
* execve() on the system is denied. Keep that window out of the cheap failure paths above. */
_cleanup_(restrict_fsaccess_bpf_freep) struct restrict_fsaccess_bpf *obj = NULL;
r = bpf_restrict_fsaccess_prepare(&obj);
if (r < 0)
@@ -259,10 +256,6 @@ static int do_check(void) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"bpf-restrict-fsaccess: Failed to link program.");
if (!dm_verity_require_signatures())
return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "dm-verity require_signatures is not enabled.");
log_info("dm-verity require_signatures: enabled");
return 0;
}
@@ -90,9 +90,8 @@ testcase_no_require_signatures_helper() {
fi
fi
# The helper's "check" command runs the same bpf_restrict_fsaccess_supported()
# and dm_verity_require_signatures() checks that PID1 uses. It must fail
# because require_signatures is not enabled.
# The helper's "check" command runs the same bpf_restrict_fsaccess_check_prerequisites()
# checks that PID1 uses. It must fail because require_signatures is not enabled.
if "$HELPER" check; then
echo "ERROR: helper check succeeded but require_signatures is not enabled"
return 1