[PATCH v5 bpf-next 0/5] bpf path iterator

NeilBrown neil at brown.name
Wed Jun 25 23:04:56 UTC 2025


On Wed, 25 Jun 2025, Mickaël Salaün wrote:
> On Wed, Jun 25, 2025 at 07:38:53AM +1000, NeilBrown wrote:
> > 
> > Can you spell out the minimum that you need?
> 
> Sure.  We'd like to call this new helper in a RCU
> read-side critical section and leverage this capability to speed up path
> walk when there is no concurrent hierarchy modification.  This use case
> is similar to handle_dots() with LOOKUP_RCU calling follow_dotdot_rcu().
> 
> The main issue with this approach is to keep some state of the path walk
> to know if the next call to "path_walk_parent_rcu()" would be valid
> (i.e. something like a very light version of nameidata, mainly sequence
> integers), and to get back to the non-RCU version otherwise.
> 
> > 
> > My vague impression is that you want to search up from a given strut path,
> > no further then some other given path, looking for a dentry that matches
> > some rule.  Is that correct?
> 
> Yes
> 
> > 
> > In general, the original dentry could be moved away from under the
> > dentry you find moments after the match is reported.  What mechanisms do
> > you have in place to ensure this doesn't happen, or that it doesn't
> > matter?
> 
> In the case of Landlock, by default, a set of access rights are denied
> and can only be allowed by an element in the file hierarchy.  The goal
> is to only allow access to files under a specific directory (or directly
> a specific file).  That's why we only care of the file hierarchy at the
> time of access check.  It's not an issue if the file/directory was
> moved or is being moved as long as we can walk its "current" hierarchy.
> Furthermore, a sandboxed process is restricted from doing arbitrary
> mounts (and renames/links are controlled with the
> LANDLOCK_ACCESS_FS_REFER right).
> 
> However, we need to get a valid "snapshot" of the set of dentries that
> (could) lead to the evaluated file/directory.

A "snapshot" is an interesting idea - though looking at the landlock
code you one need inodes, not dentries.
I imagine an interface where you give it a starting path, a root, and
and array of inode pointers, and it fills in the pointers with the path
- all under rcu so no references are needed.
But you would need some fallback if the array isn't big enough, so maybe
that isn't a good idea.

Based on the comments by Al and Christian, I think the only viable
approach is to pass a callback to some vfs function that does the
walking.

   vfs_walk_ancestors(struct path *path, struct path *root,
		      int (*walk_cb)(struct path *ancestor, void *data),
		      void *data)

where walk_cb() returns a negative number if it wants to abort, and is
given a NULL ancestor if vfs_walk_ancestors() needed to restart.

vfs_walk_ancestors() would initialise a "struct nameidata" and
effectively call handle_dots(&nd, LAST_DOTDOT) repeatedly, calling
    walk_cb(&nd.path, data)
each time.

How would you feel about that sort of interface?

NeilBrown



More information about the Linux-security-module-archive mailing list