From: "Mickaël Salaün" <mic@digikod.net>
To: "Günther Noack" <gnoack@google.com>
Cc: "Mickaël Salaün" <mic@digikod.net>,
"Ada Smith" <adasmithgt@gmail.com>,
"Hungyu Lin" <dennylin0707@gmail.com>,
"James Morris" <jmorris@namei.org>,
"Josef Bacik" <josef@toxicpanda.com>,
"Paul Moore" <paul@paul-moore.com>,
"Serge Hallyn" <serge@hallyn.com>,
kernel-team@cloudflare.com, linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org
Subject: [PATCH 5/6] selftests/landlock: Test capability checks outside the capable hook
Date: Tue, 10 Nov 2026 21:24:33 +0100 [thread overview]
Message-ID: <20261110202436.2408244-6-mic@digikod.net> (raw)
In-Reply-To: <20261110202436.2408244-1-mic@digikod.net>
The previous commits make Landlock restrict the capability checks that
commoncap makes from LSM hooks other than capable, which no test covers:
mapping below vm.mmap_min_addr (CAP_SYS_RAWIO), adding inheritable
capabilities outside of the permitted set (CAP_SETPCAP), and using the
admin memory reserve under vm.overcommit_memory=2 (CAP_SYS_ADMIN).
Each test first checks that the operation fails without the capability,
so that it exercises the capability check, and then checks it with the
capability effective in four variants: unsandboxed, in a domain that
denies the capability, in a domain that allows it, and in a domain that
does not handle capabilities.
Audit tests check that the capset and mmap_addr denials are logged, that
the admin reserve check is not, and that allowed uses log nothing.
The admin reserve test has to change system-wide overcommit settings: it
sets a commit limit that only fits its mapping with the reserve, with
margins of 96 MiB for other processes. It changes them after the
fixture setup, so that the teardown restores them after any failure, and
it only runs as root (EUID 0) while writing them.
Add CAP_SYS_RAWIO to the capabilities that the tests may raise, and drop
the stale count from the comment of this list.
Without the fixes, the three denied variants and the denial audit test
fail.
Cc: Günther Noack <gnoack@google.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
---
tools/testing/selftests/landlock/cap_test.c | 535 ++++++++++++++++++++
tools/testing/selftests/landlock/common.h | 4 +-
2 files changed, 538 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/landlock/cap_test.c b/tools/testing/selftests/landlock/cap_test.c
index 3d7fd02e21ed..c79bb42c6282 100644
--- a/tools/testing/selftests/landlock/cap_test.c
+++ b/tools/testing/selftests/landlock/cap_test.c
@@ -12,7 +12,9 @@
#include <linux/landlock.h>
#include <sched.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/xattr.h>
@@ -738,6 +740,451 @@ TEST(cap_target_userns_independent)
EXPECT_EQ(0, close(target_userns_fd));
}
+/*
+ * Capability checks that commoncap makes from hooks other than the capable
+ * hook. Each test first checks that the operation needs the capability, then
+ * checks it with the capability effective. Variants cover an unsandboxed
+ * baseline, a domain that denies the capability, a domain that allows it, and a
+ * domain that does not handle capabilities.
+ */
+/* clang-format off */
+FIXTURE(cap_other_hooks) {};
+/* clang-format on */
+
+FIXTURE_VARIANT(cap_other_hooks)
+{
+ const bool is_sandboxed;
+ const bool handle_caps;
+ const bool is_allowed;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_other_hooks, unsandboxed) {
+ .is_sandboxed = false,
+ .handle_caps = false,
+ .is_allowed = true,
+};
+/* clang-format on */
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_other_hooks, denied) {
+ .is_sandboxed = true,
+ .handle_caps = true,
+ .is_allowed = false,
+};
+/* clang-format on */
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_other_hooks, allowed) {
+ .is_sandboxed = true,
+ .handle_caps = true,
+ .is_allowed = true,
+};
+/* clang-format on */
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_other_hooks, unhandled) {
+ .is_sandboxed = true,
+ .handle_caps = false,
+ .is_allowed = true,
+};
+/* clang-format on */
+
+FIXTURE_SETUP(cap_other_hooks)
+{
+ disable_caps(_metadata);
+}
+
+FIXTURE_TEARDOWN(cap_other_hooks)
+{
+}
+
+/*
+ * Creates a ruleset that handles capabilities and allows @cap if @is_allowed,
+ * or, if !@handle_caps, a ruleset that only handles a filesystem access right.
+ * Returns the ruleset FD, or -1 with errno set.
+ */
+static int create_variant_ruleset(const bool handle_caps, const bool is_allowed,
+ const int cap)
+{
+ const struct landlock_ruleset_attr fs_attr = {
+ .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
+ };
+ int ruleset_fd, err;
+
+ if (!handle_caps)
+ return landlock_create_ruleset(&fs_attr, sizeof(fs_attr), 0);
+
+ ruleset_fd = create_cap_ruleset();
+ if (ruleset_fd < 0 || !is_allowed)
+ return ruleset_fd;
+
+ if (add_cap_rule(ruleset_fd, cap)) {
+ err = errno;
+ close(ruleset_fd);
+ errno = err;
+ return -1;
+ }
+ return ruleset_fd;
+}
+
+static void
+enforce_cap_variant(struct __test_metadata *const _metadata,
+ const FIXTURE_VARIANT(cap_other_hooks) *const variant,
+ const int cap)
+{
+ int ruleset_fd;
+
+ if (!variant->is_sandboxed)
+ return;
+
+ ruleset_fd = create_variant_ruleset(variant->handle_caps,
+ variant->is_allowed, cap);
+ ASSERT_LE(0, ruleset_fd);
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+}
+
+static unsigned long read_sysctl(struct __test_metadata *const _metadata,
+ const char *const path)
+{
+ char buf[32];
+ ssize_t len;
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CLOEXEC);
+ ASSERT_LE(0, fd)
+ {
+ TH_LOG("Failed to open %s: %s", path, strerror(errno));
+ }
+ len = read(fd, buf, sizeof(buf) - 1);
+ ASSERT_LT(0, len);
+ EXPECT_EQ(0, close(fd));
+
+ buf[len] = '\0';
+ return strtoul(buf, NULL, 10);
+}
+
+/* Returns 0 on success, or -1 with errno set. */
+static int write_sysctl(const char *const path, const unsigned long value)
+{
+ char buf[32];
+ int fd, len, err = 0;
+ ssize_t ret;
+
+ len = snprintf(buf, sizeof(buf), "%lu", value);
+ fd = open(path, O_WRONLY | O_CLOEXEC);
+ if (fd < 0)
+ return -1;
+ ret = write(fd, buf, len);
+ if (ret != len) {
+ if (ret >= 0)
+ errno = EIO;
+ err = -1;
+ }
+ if (close(fd) && !err)
+ err = -1;
+ return err;
+}
+
+/*
+ * cap_mmap_addr() requires CAP_SYS_RAWIO to map below the vm.mmap_min_addr
+ * sysctl (dac_mmap_min_addr).
+ */
+TEST_F(cap_other_hooks, mmap_min_addr)
+{
+ const size_t page_size = sysconf(_SC_PAGESIZE);
+ void *addr;
+
+ if (read_sysctl(_metadata, "/proc/sys/vm/mmap_min_addr") == 0)
+ SKIP(return, "vm.mmap_min_addr is 0");
+
+ enforce_cap_variant(_metadata, variant, CAP_SYS_RAWIO);
+
+ addr = mmap(NULL, page_size, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ EXPECT_EQ(MAP_FAILED, addr);
+ EXPECT_EQ(EPERM, errno);
+
+ set_cap(_metadata, CAP_SYS_RAWIO);
+ addr = mmap(NULL, page_size, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ if (variant->is_allowed) {
+ EXPECT_EQ(NULL, addr)
+ {
+ TH_LOG("Failed to map page 0: %s", strerror(errno));
+ }
+ if (addr != MAP_FAILED)
+ EXPECT_EQ(0, munmap(addr, page_size));
+ } else {
+ EXPECT_EQ(MAP_FAILED, addr);
+ EXPECT_EQ(EPERM, errno);
+ if (addr != MAP_FAILED)
+ munmap(addr, page_size);
+ }
+ clear_cap(_metadata, CAP_SYS_RAWIO);
+}
+
+static int add_inheritable_cap(const cap_value_t cap)
+{
+ cap_t cap_p;
+ int ret, err;
+
+ cap_p = cap_get_proc();
+ if (!cap_p)
+ return -1;
+
+ ret = cap_set_flag(cap_p, CAP_INHERITABLE, 1, &cap, CAP_SET);
+ if (!ret)
+ ret = cap_set_proc(cap_p);
+ err = errno;
+ cap_free(cap_p);
+ errno = err;
+ return ret;
+}
+
+/*
+ * cap_capset() requires CAP_SETPCAP to add an inheritable capability that is
+ * not in the permitted set. CAP_NET_RAW is in the bounding set, but
+ * disable_caps() does not put it in the permitted set.
+ */
+TEST_F(cap_other_hooks, capset_inheritable)
+{
+ enforce_cap_variant(_metadata, variant, CAP_SETPCAP);
+
+ EXPECT_EQ(-1, add_inheritable_cap(CAP_NET_RAW));
+ EXPECT_EQ(EPERM, errno);
+
+ set_cap(_metadata, CAP_SETPCAP);
+ if (variant->is_allowed) {
+ EXPECT_EQ(0, add_inheritable_cap(CAP_NET_RAW))
+ {
+ TH_LOG("Failed to raise CAP_NET_RAW: %s",
+ strerror(errno));
+ }
+ } else {
+ EXPECT_EQ(-1, add_inheritable_cap(CAP_NET_RAW));
+ EXPECT_EQ(EPERM, errno);
+ }
+ clear_cap(_metadata, CAP_SETPCAP);
+}
+
+/*
+ * With vm.overcommit_memory=2, cap_vm_enough_memory() lets CAP_SYS_ADMIN use
+ * the vm.admin_reserve_kbytes reserve. The test sets a commit limit that
+ * leaves room for the test mapping only with the reserve, and keeps some room
+ * for other processes. The fixture setup only saves the settings, so that the
+ * teardown restores them after any failure once they are changed.
+ */
+#define OVERCOMMIT_PATH "/proc/sys/vm/"
+#define ADMIN_RESERVE_KB (256UL * 1024)
+#define HEADROOM_KB (64UL * 1024)
+#define MAPPING_KB (160UL * 1024)
+
+/* clang-format off */
+FIXTURE(cap_admin_reserve) {
+ /* clang-format on */
+ unsigned long overcommit_memory, overcommit_kbytes, overcommit_ratio;
+ unsigned long admin_reserve_kbytes, committed;
+ bool is_set;
+};
+
+FIXTURE_VARIANT(cap_admin_reserve)
+{
+ const bool is_sandboxed;
+ const bool handle_caps;
+ const bool is_allowed;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_admin_reserve, unsandboxed) {
+ .is_sandboxed = false,
+ .handle_caps = false,
+ .is_allowed = true,
+};
+/* clang-format on */
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_admin_reserve, denied) {
+ .is_sandboxed = true,
+ .handle_caps = true,
+ .is_allowed = false,
+};
+/* clang-format on */
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_admin_reserve, allowed) {
+ .is_sandboxed = true,
+ .handle_caps = true,
+ .is_allowed = true,
+};
+/* clang-format on */
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(cap_admin_reserve, unhandled) {
+ .is_sandboxed = true,
+ .handle_caps = false,
+ .is_allowed = true,
+};
+/* clang-format on */
+
+static unsigned long read_committed_kb(struct __test_metadata *const _metadata)
+{
+ unsigned long committed = 0;
+ char line[128];
+ FILE *file;
+
+ file = fopen("/proc/meminfo", "re");
+ ASSERT_NE(NULL, file);
+
+ while (fgets(line, sizeof(line), file))
+ if (sscanf(line, "Committed_AS: %lu kB", &committed) == 1)
+ break;
+
+ EXPECT_EQ(0, fclose(file));
+ EXPECT_NE(0, committed);
+ return committed;
+}
+
+/*
+ * sysctl_perm() only lets the root user write the vm.* sysctls. Switching to
+ * EUID 0 raises all permitted capabilities, so drop them again.
+ */
+static void set_root_euid(struct __test_metadata *const _metadata)
+{
+ set_cap(_metadata, CAP_SETUID);
+ ASSERT_EQ(0, seteuid(0));
+ disable_caps(_metadata);
+}
+
+/*
+ * Switching back to the real UID needs no capability. Keep the permitted
+ * capabilities, which the setuid fixup would otherwise clear.
+ */
+static void restore_euid(struct __test_metadata *const _metadata)
+{
+ ASSERT_EQ(0, prctl(PR_SET_KEEPCAPS, 1));
+ ASSERT_EQ(0, seteuid(getuid()));
+ disable_caps(_metadata);
+}
+
+FIXTURE_SETUP(cap_admin_reserve)
+{
+ self->is_set = false;
+ disable_caps(_metadata);
+
+ self->overcommit_memory =
+ read_sysctl(_metadata, OVERCOMMIT_PATH "overcommit_memory");
+ self->overcommit_kbytes =
+ read_sysctl(_metadata, OVERCOMMIT_PATH "overcommit_kbytes");
+ self->overcommit_ratio =
+ read_sysctl(_metadata, OVERCOMMIT_PATH "overcommit_ratio");
+ self->admin_reserve_kbytes =
+ read_sysctl(_metadata, OVERCOMMIT_PATH "admin_reserve_kbytes");
+ self->committed = read_committed_kb(_metadata);
+ ASSERT_NE(0, self->committed);
+}
+
+FIXTURE_TEARDOWN(cap_admin_reserve)
+{
+ if (!self->is_set)
+ return;
+
+ /* Restores every value, even if one of the writes fails. */
+ set_cap(_metadata, CAP_SETUID);
+ EXPECT_EQ(0, seteuid(0));
+ disable_caps(_metadata);
+ EXPECT_EQ(0, write_sysctl(OVERCOMMIT_PATH "overcommit_memory",
+ self->overcommit_memory));
+ /* Writing one of these two resets the other to 0. */
+ if (self->overcommit_kbytes) {
+ EXPECT_EQ(0, write_sysctl(OVERCOMMIT_PATH "overcommit_kbytes",
+ self->overcommit_kbytes));
+ } else {
+ EXPECT_EQ(0, write_sysctl(OVERCOMMIT_PATH "overcommit_ratio",
+ self->overcommit_ratio));
+ }
+ EXPECT_EQ(0, write_sysctl(OVERCOMMIT_PATH "admin_reserve_kbytes",
+ self->admin_reserve_kbytes));
+ restore_euid(_metadata);
+}
+
+/*
+ * Called from the test, after the fixture setup, so that the teardown restores
+ * the settings if any of these writes fails.
+ */
+static void set_admin_reserve(struct __test_metadata *const _metadata,
+ FIXTURE_DATA(cap_admin_reserve) *const self)
+{
+ set_root_euid(_metadata);
+ self->is_set = true;
+ ASSERT_EQ(0, write_sysctl(OVERCOMMIT_PATH "admin_reserve_kbytes",
+ ADMIN_RESERVE_KB));
+ ASSERT_EQ(0, write_sysctl(OVERCOMMIT_PATH "overcommit_kbytes",
+ self->committed + ADMIN_RESERVE_KB +
+ HEADROOM_KB));
+ ASSERT_EQ(0, write_sysctl(OVERCOMMIT_PATH "overcommit_memory", 2));
+ restore_euid(_metadata);
+}
+
+/* Returns 0 if a writable private mapping of MAPPING_KB fits, or errno. */
+static int
+test_admin_reserve(const FIXTURE_VARIANT(cap_admin_reserve) *const variant,
+ const bool is_admin)
+{
+ const size_t size = MAPPING_KB * 1024;
+ int ruleset_fd, status;
+ void *addr;
+ pid_t child;
+
+ child = fork();
+ if (child < 0)
+ return errno;
+
+ if (child == 0) {
+ if (variant->is_sandboxed) {
+ ruleset_fd = create_variant_ruleset(
+ variant->handle_caps, variant->is_allowed,
+ CAP_SYS_ADMIN);
+ if (ruleset_fd < 0)
+ _exit(255);
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
+ landlock_restrict_self(ruleset_fd, 0))
+ _exit(255);
+ close(ruleset_fd);
+ }
+
+ if (is_admin) {
+ cap_t cap_p = cap_get_proc();
+ const cap_value_t cap = CAP_SYS_ADMIN;
+
+ if (!cap_p ||
+ cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap,
+ CAP_SET) ||
+ cap_set_proc(cap_p))
+ _exit(255);
+ cap_free(cap_p);
+ }
+
+ addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ _exit(addr == MAP_FAILED ? errno : 0);
+ }
+
+ if (waitpid(child, &status, 0) != child || !WIFEXITED(status))
+ return 255;
+ return WEXITSTATUS(status);
+}
+
+TEST_F(cap_admin_reserve, mmap)
+{
+ set_admin_reserve(_metadata, self);
+
+ EXPECT_EQ(ENOMEM, test_admin_reserve(variant, false));
+ EXPECT_EQ(variant->is_allowed ? 0 : ENOMEM,
+ test_admin_reserve(variant, true));
+}
+
/* Audit tests */
static int matches_log_cap(int audit_fd, int cap_number)
@@ -828,6 +1275,94 @@ TEST_F(cap_audit, denied)
EXPECT_EQ(0, records.domain);
}
+/*
+ * Denials in the capset and mmap_addr paths are audited like capable hook
+ * denials. The vm_enough_memory hook only withholds the admin reserve, with
+ * CAP_OPT_NOAUDIT, so an accounted mapping made with CAP_SYS_ADMIN effective
+ * leaves no record.
+ */
+TEST_F(cap_audit, other_hooks)
+{
+ const size_t page_size = sysconf(_SC_PAGESIZE);
+ struct audit_records records = {};
+ int ruleset_fd;
+ __u64 domain_id;
+ void *addr;
+
+ ruleset_fd = create_cap_ruleset();
+ ASSERT_LE(0, ruleset_fd);
+ /* Allow CAP_AUDIT_CONTROL for child-side audit cleanup. */
+ ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL));
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+
+ set_cap(_metadata, CAP_SETPCAP);
+ EXPECT_EQ(-1, add_inheritable_cap(CAP_NET_RAW));
+ EXPECT_EQ(EPERM, errno);
+ clear_cap(_metadata, CAP_SETPCAP);
+ EXPECT_EQ(0, matches_log_cap(self->audit_fd, CAP_SETPCAP));
+ EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(),
+ &domain_id));
+
+ /* The mmap_addr hook has nothing to check without a limit. */
+ if (read_sysctl(_metadata, "/proc/sys/vm/mmap_min_addr")) {
+ set_cap(_metadata, CAP_SYS_RAWIO);
+ addr = mmap(NULL, page_size, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ EXPECT_EQ(MAP_FAILED, addr);
+ EXPECT_EQ(EPERM, errno);
+ clear_cap(_metadata, CAP_SYS_RAWIO);
+ EXPECT_EQ(0, matches_log_cap(self->audit_fd, CAP_SYS_RAWIO));
+ }
+
+ set_cap(_metadata, CAP_SYS_ADMIN);
+ addr = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ EXPECT_NE(MAP_FAILED, addr);
+ clear_cap(_metadata, CAP_SYS_ADMIN);
+ if (addr != MAP_FAILED)
+ EXPECT_EQ(0, munmap(addr, page_size));
+
+ EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
+ EXPECT_EQ(0, records.access);
+ EXPECT_EQ(0, records.domain);
+}
+
+/* Allowed capability uses in the capset and mmap_addr paths. */
+TEST_F(cap_audit, other_hooks_allowed)
+{
+ const size_t page_size = sysconf(_SC_PAGESIZE);
+ struct audit_records records = {};
+ int ruleset_fd;
+ void *addr;
+
+ ruleset_fd = create_cap_ruleset();
+ ASSERT_LE(0, ruleset_fd);
+ ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_SETPCAP));
+ ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_SYS_RAWIO));
+ /* Allow CAP_AUDIT_CONTROL for child-side audit cleanup. */
+ ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL));
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+
+ set_cap(_metadata, CAP_SETPCAP);
+ EXPECT_EQ(0, add_inheritable_cap(CAP_NET_RAW));
+ clear_cap(_metadata, CAP_SETPCAP);
+
+ if (read_sysctl(_metadata, "/proc/sys/vm/mmap_min_addr")) {
+ set_cap(_metadata, CAP_SYS_RAWIO);
+ addr = mmap(NULL, page_size, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ EXPECT_EQ(NULL, addr);
+ clear_cap(_metadata, CAP_SYS_RAWIO);
+ if (addr != MAP_FAILED)
+ EXPECT_EQ(0, munmap(addr, page_size));
+ }
+
+ EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
+ EXPECT_EQ(0, records.access);
+}
+
TEST_F(cap_audit, allowed)
{
struct audit_records records = {};
diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index e29406900c04..a6fdfb422fad 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -36,7 +36,7 @@ static const char bin_wait_pipe_sandbox[] = "./wait-pipe-sandbox";
static void _init_caps(struct __test_metadata *const _metadata, bool drop_all)
{
cap_t cap_p;
- /* Only these three capabilities are useful for the tests. */
+ /* Only these capabilities are useful for the tests. */
const cap_value_t caps[] = {
/* clang-format off */
CAP_AUDIT_CONTROL,
@@ -44,9 +44,11 @@ static void _init_caps(struct __test_metadata *const _metadata, bool drop_all)
CAP_MKNOD,
CAP_NET_ADMIN,
CAP_NET_BIND_SERVICE,
+ CAP_SETPCAP,
CAP_SETUID,
CAP_SYS_ADMIN,
CAP_SYS_CHROOT,
+ CAP_SYS_RAWIO,
/* clang-format on */
};
const unsigned int noroot = SECBIT_NOROOT | SECBIT_NOROOT_LOCKED;
--
2.56.0
next prev parent reply other threads:[~2026-11-10 20:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 20:24 [PATCH 0/6] Fix Landlock mediation of commoncap's capability checks Mickaël Salaün
2026-11-10 20:24 ` [PATCH 1/6] landlock: Factor out capability denial checks Mickaël Salaün
2026-11-10 20:24 ` [PATCH 2/6] landlock: Mediate CAP_SYS_RAWIO for mappings below mmap_min_addr Mickaël Salaün
2026-11-10 20:24 ` [PATCH 3/6] landlock: Mediate CAP_SETPCAP for inheritable capabilities Mickaël Salaün
2026-11-10 20:24 ` [PATCH 4/6] landlock: Mediate CAP_SYS_ADMIN for the admin memory reserve Mickaël Salaün
2026-11-10 20:24 ` Mickaël Salaün [this message]
2026-11-10 20:24 ` [PATCH 6/6] landlock: Fix capability restriction documentation Mickaël Salaün
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261110202436.2408244-6-mic@digikod.net \
--to=mic@digikod.net \
--cc=adasmithgt@gmail.com \
--cc=dennylin0707@gmail.com \
--cc=gnoack@google.com \
--cc=jmorris@namei.org \
--cc=josef@toxicpanda.com \
--cc=kernel-team@cloudflare.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®