[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