[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAPhsuW7mwut7SYubAUa5Ji7meDP1Bn8ZD9s+4sqjBDim7jGrWA@mail.gmail.com>
Date: Tue, 3 Jun 2025 14:09:20 -0700
From: Song Liu <song@...nel.org>
To: Andrii Nakryiko <andrii.nakryiko@...il.com>
Cc: bpf@...r.kernel.org, linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-security-module@...r.kernel.org,
kernel-team@...a.com, andrii@...nel.org, eddyz87@...il.com, ast@...nel.org,
daniel@...earbox.net, martin.lau@...ux.dev, viro@...iv.linux.org.uk,
brauner@...nel.org, jack@...e.cz, kpsingh@...nel.org,
mattbobrowski@...gle.com, amir73il@...il.com, repnop@...gle.com,
jlayton@...nel.org, josef@...icpanda.com, mic@...ikod.net, gnoack@...gle.com,
m@...wtm.org
Subject: Re: [PATCH v2 bpf-next 3/4] bpf: Introduce path iterator
On Tue, Jun 3, 2025 at 11:40 AM Andrii Nakryiko
<andrii.nakryiko@...il.com> wrote:
[...]
> > +__bpf_kfunc struct path *bpf_iter_path_next(struct bpf_iter_path *it)
> > +{
> > + struct bpf_iter_path_kern *kit = (void *)it;
> > + struct path root = {};
> > +
> > + if (!path_walk_parent(&kit->path, &root))
> > + return NULL;
> > + return &kit->path;
> > +}
> > +
> > +__bpf_kfunc void bpf_iter_path_destroy(struct bpf_iter_path *it)
> > +{
> > + struct bpf_iter_path_kern *kit = (void *)it;
> > +
> > + path_put(&kit->path);
>
> note, destroy() will be called even if construction of iterator fails
> or we exhausted iterator. So you need to make sure that you have
> bpf_iter_path state where you can detect that there is no path present
> and skip path_put().
In bpf_iter_path_next(), when path_walk_parent() returns false, we
still hold reference to kit->path, then _destroy() will release it. So we
should be fine, no?
Thanks,
Song
>
> > +}
> > +
> > +__bpf_kfunc_end_defs();
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index a7d6e0c5928b..45b45cdfb223 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -7036,6 +7036,10 @@ BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct socket) {
> > struct sock *sk;
> > };
> >
> > +BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct path) {
> > + struct dentry *dentry;
> > +};
> > +
> > static bool type_is_rcu(struct bpf_verifier_env *env,
> > struct bpf_reg_state *reg,
> > const char *field_name, u32 btf_id)
> > @@ -7076,6 +7080,7 @@ static bool type_is_trusted_or_null(struct bpf_verifier_env *env,
> > const char *field_name, u32 btf_id)
> > {
> > BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct socket));
> > + BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct path));
> >
> > return btf_nested_type_is_trusted(&env->log, reg, field_name, btf_id,
> > "__safe_trusted_or_null");
> > --
> > 2.47.1
> >
>
Powered by blists - more mailing lists