[PATCH bpf-next 2/3] bpf: Add bpf_kern_path and bpf_path_put kfuncs
Song Liu
song at kernel.org
Sun Nov 30 05:57:43 UTC 2025
On Sat, Nov 29, 2025 at 8:23 PM Al Viro <viro at zeniv.linux.org.uk> wrote:
>
> On Wed, Nov 26, 2025 at 04:50:06PM -0800, Song Liu wrote:
> > Add two new kfuncs to fs/bpf_fs_kfuncs.c that wrap kern_path() for use
> > by BPF LSM programs:
> >
> > bpf_kern_path():
> > - Resolves a pathname string to a struct path
>
> > These kfuncs enable BPF LSM programs to resolve pathnames provided by
> > hook arguments (e.g., dev_name from sb_mount) and validate or inspect
> > the resolved paths. The verifier enforces proper resource management
> > through acquire/release tracking.
>
> Oh, *brilliant*. Thank you for giving a wonderful example of the reasons
> why this is fundamentally worthless.
>
> OK, your "BPF LSM" has been called and it got that dev_name. You decide
> that you want to know what it resolves to (which, BTW, requries a really
> non-trivial amount of parsing other arguments - just to figure out whether
> it *is* a pathname of some sort). Thanks to your shiny new kfuncs you
> can do that! You are a proud holder of mount/dentry pair. You stare at
> those and decide whether it's OK to go on. Then you... drop that pair
> and let mount(2) proceed towards the point where it will (if you parsed
> the arguments correctly) repeat that pathname resolution and get a mount/dentry
> pair of its own, that may very well be different from what you've got the
> first time around.
>
> Your primitive is a walking TOCTOU bug - it's impossible to use safely.
Good point. AFAICT, the sample TOCTOU bug applies to other LSMs that
care about dev_name in sb_mount, namely, aa_bind_mount() for apparmor
and tomoyo_mount_acl() for tomoyo.
What would you recommend to do this properly? How about we add a new
LSM hook that works on the actual mount/dentry pair? Something like:
diff --git i/fs/namespace.c w/fs/namespace.c
index d82910f33dc4..3d5dc167f15f 100644
--- i/fs/namespace.c
+++ w/fs/namespace.c
@@ -2984,6 +2984,10 @@ static int do_loopback(const struct path *path,
const char *old_name,
if (err)
return err;
+ err = security_mount_loopback(old_path, path, recurse);
+ if (err)
+ return err;
+
if (mnt_ns_loop(old_path.dentry))
return -EINVAL;
(Or s/security_mount_loopback/some_other_name).
In other words, do you think we should go [1] by Shervin Oloumi?
CCing Shervin here.
We will also need something similar to cover move mount operation
via path_mount()=>do_move_mount_old()=>do_move_mount().
Thanks,
Song
[1] https://lore.kernel.org/linux-security-module/20250110021008.2704246-1-enlightened@chromium.org/
More information about the Linux-security-module-archive
mailing list