* landlock bug: procfs denials because inodes have unstable identity
@ 2026-10-30 15:45 Günther Noack
0 siblings, 0 replies; only message in thread
From: Günther Noack @ 2026-10-30 15:45 UTC (permalink / raw)
To: Mickaël Salaün
Cc: linux-security-module, linux-fsdevel, Tingmao Wang, Justin Suess
Hello!
The Landlock LSM lets processes define policies which are attached to
struct inode objects internally. As a consequence, if filesystems
forget these inodes and start using new inode objects for the same
files or directories later on, these policies do not work as intended
any more.
As it turns out, procfs has that property as well and can lose inode
identities over time, even though it does not happen immediately.
In my understanding, this is not intended. Landlock has explicit
selftests to exercise that Landlock policies work in Procfs.
For reference, similar issues have been investigated also for hostfs
[1] and 9p [2]:
[1] https://lore.kernel.org/all/20230309165455.175131-2-mic@digikod.net/
[2] https://lore.kernel.org/all/cover.1756935780.git.m@maowtm.org/
Steps to reproduce
==================
Process A:
* Enter a Landlock domain where access to /proc/sys/kernel/random
(and files below it) is allowed.
* Repeatedly open and close the boot_id file from that same directory
At the same time, the dentry caches get freed up.
We can emulate this by writing to /proc/sys/vm/drop_caches from
another (root) process:
# echo 2 > /proc/sys/vm/drop_caches
Observed result: Process A fails because of a Landlock refusal opening
the boot_id file. When Landlock walks the path for the check, the
inodes have now a different identity than before and don't match, so
Landlock denies the operation.
Expected result: Dropping the caches should not affect Landlock's
behaviour.
At the bottom of this email, I am including the source code for a
program that does Process A -- you can run this to reproduce, and then
write into the drop_caches file from another process as root.
Solution...?
============
I don't have a fix for it yet.
I am open to suggestions. Is this feasible to change in procfs?
—Günther
Reproducer program, for easier reproduction (don't forget to drop
caches in parallel):
---landlock_uuid.c
#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <linux/landlock.h>
#include <stddef.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
static int landlock_create_ruleset(struct landlock_ruleset_attr *attr,
size_t size, __u32 flags)
{
return syscall(__NR_landlock_create_ruleset, attr, size, flags);
}
static int landlock_add_rule(int ruleset_fd, enum landlock_rule_type rule_type,
void *rule_attr, __u32 flags)
{
return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type,
rule_attr, flags);
}
static int landlock_restrict_self(int ruleset_fd, __u32 flags)
{
return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
}
int main(void)
{
struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs =
LANDLOCK_ACCESS_FS_EXECUTE |
LANDLOCK_ACCESS_FS_WRITE_FILE |
LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_READ_DIR |
LANDLOCK_ACCESS_FS_REMOVE_DIR |
LANDLOCK_ACCESS_FS_REMOVE_FILE |
LANDLOCK_ACCESS_FS_MAKE_CHAR |
LANDLOCK_ACCESS_FS_MAKE_DIR |
LANDLOCK_ACCESS_FS_MAKE_REG |
LANDLOCK_ACCESS_FS_MAKE_SOCK |
LANDLOCK_ACCESS_FS_MAKE_FIFO |
LANDLOCK_ACCESS_FS_MAKE_BLOCK |
LANDLOCK_ACCESS_FS_MAKE_SYM |
LANDLOCK_ACCESS_FS_REFER |
LANDLOCK_ACCESS_FS_TRUNCATE |
LANDLOCK_ACCESS_FS_IOCTL_DEV |
LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
};
/*
* Backwards compatibility checks omitted for brevity.
* Assuming Linux 7.3 here. :)
*/
int ruleset_fd = landlock_create_ruleset(&ruleset_attr,
sizeof(ruleset_attr), 0);
if (ruleset_fd < 0)
err(1, "landlock_create_ruleset");
int parent_fd = open("/proc/sys/kernel/random", O_PATH | O_CLOEXEC);
if (parent_fd < 0)
err(1, "open(/proc/sys/kernel/random)");
struct landlock_path_beneath_attr path_beneath = {
.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE,
.parent_fd = parent_fd,
};
if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
&path_beneath, 0) < 0)
err(1, "landlock_add_rule");
close(parent_fd);
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0)
err(1, "prctl(PR_SET_NO_NEW_PRIVS)");
if (landlock_restrict_self(ruleset_fd, 0) < 0)
err(1, "landlock_restrict_self");
close(ruleset_fd);
/* Print out the boot_id file once a second. */
for (;;) {
int fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY);
if (fd < 0)
err(1, "open(/proc/sys/kernel/random/boot_id)");
char buf[64];
ssize_t n;
while ((n = read(fd, buf, sizeof(buf))) > 0) {
if (write(STDOUT_FILENO, buf, n) < 0)
err(1, "write");
}
if (n < 0)
err(1, "read");
close(fd);
sleep(1);
}
return 0;
}
---
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-30 15:45 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 15:45 landlock bug: procfs denials because inodes have unstable identity Günther Noack
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.