Add a sleepable BPF kfunc that resolves the real inode backing a dentry via d_real_inode(). On overlay/union filesystems the inode attached to the dentry is the overlay inode which does not carry the underlying device information. d_real_inode() resolves through the overlay and returns the inode from the lower, real filesystem. This is used in the RestrictFilesytemAccess bpf program that has been merged into systemd a little while ago. Link: https://github.com/systemd/systemd/pull/41340 [1] Signed-off-by: Christian Brauner (Amutable) --- Changes in v2: - Tag bpf_real_inode() with KF_RET_NULL and document that it returns NULL for negative dentries; LSM hooks such as security_inode_create() pass negative dentries, and without the flag the verifier marks the return as PTR_TRUSTED and skips the NULL check. - Link to v1: https://patch.msgid.link/20260326-work-bpf-verity-v1-1-efe9edc46ddc@kernel.org --- fs/bpf_fs_kfuncs.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fs/bpf_fs_kfuncs.c b/fs/bpf_fs_kfuncs.c index e4e51a1d0de2..761fbe0fec5d 100644 --- a/fs/bpf_fs_kfuncs.c +++ b/fs/bpf_fs_kfuncs.c @@ -353,6 +353,21 @@ __bpf_kfunc int bpf_cgroup_read_xattr(struct cgroup *cgroup, const char *name__s } #endif /* CONFIG_CGROUPS */ +/** + * bpf_real_inode - get the real inode backing a dentry + * @dentry: dentry to resolve + * + * If the dentry is on a union/overlay filesystem, return the underlying, real + * inode that hosts the data. Otherwise return the inode attached to the + * dentry itself. + * + * Return: The real inode backing the dentry, or NULL for a negative dentry. + */ +__bpf_kfunc struct inode *bpf_real_inode(struct dentry *dentry) +{ + return d_real_inode(dentry); +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(bpf_fs_kfunc_set_ids) @@ -363,6 +378,7 @@ BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_set_dentry_xattr, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_remove_dentry_xattr, KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_real_inode, KF_SLEEPABLE | KF_RET_NULL) BTF_KFUNCS_END(bpf_fs_kfunc_set_ids) static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id) --- base-commit: 1f318b96cc84d7c2ab792fcc0bfd42a7ca890681 change-id: 20260326-work-bpf-verity-a43f28baa242