From: KP Singh <kpsingh@chromium.org>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: KP Singh <kpsingh@chromium.org>,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
bpf@vger.kernel.org, linux-security-module@vger.kernel.org,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
James Morris <jmorris@namei.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Martin KaFai Lau <kafai@fb.com>, Jann Horn <jannh@google.com>,
Florent Revest <revest@chromium.org>
Subject: Re: [PATCH bpf-next 2/4] bpf: Implement bpf_local_storage for inodes
Date: Wed, 27 May 2020 04:11:11 +0200 [thread overview]
Message-ID: <20200527021111.GA197666@google.com> (raw)
In-Reply-To: <20200527004902.lo6c2efv5vix5nqq@ast-mbp.dhcp.thefacebook.com>
Thanks for taking a look!
On 26-May 17:49, Alexei Starovoitov wrote:
> On Tue, May 26, 2020 at 06:33:34PM +0200, KP Singh wrote:
> >
> > +static struct bpf_local_storage_data *inode_storage_update(
> > + struct inode *inode, struct bpf_map *map, void *value, u64 map_flags)
> > +{
> > + struct bpf_local_storage_data *old_sdata = NULL;
> > + struct bpf_local_storage_elem *selem;
> > + struct bpf_local_storage *local_storage;
> > + struct bpf_local_storage_map *smap;
> > + int err;
> > +
> > + err = check_update_flags(map, map_flags);
> > + if (err)
> > + return ERR_PTR(err);
> > +
> > + smap = (struct bpf_local_storage_map *)map;
> > + local_storage = rcu_dereference(inode->inode_bpf_storage);
> > +
> > + if (!local_storage || hlist_empty(&local_storage->list)) {
> > + /* Very first elem for this inode */
> > + err = check_flags(NULL, map_flags);
> > + if (err)
> > + return ERR_PTR(err);
> > +
> > + selem = selem_alloc(smap, value);
> > + if (!selem)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + err = inode_storage_alloc(inode, smap, selem);
>
> inode_storage_update looks like big copy-paste except above one line.
> pls consolidate.
Sure.
>
> > +BPF_CALL_4(bpf_inode_storage_get, struct bpf_map *, map, struct inode *, inode,
> > + void *, value, u64, flags)
> > +{
> > + struct bpf_local_storage_data *sdata;
> > +
> > + if (flags > BPF_LOCAL_STORAGE_GET_F_CREATE)
> > + return (unsigned long)NULL;
> > +
> > + sdata = inode_storage_lookup(inode, map, true);
> > + if (sdata)
> > + return (unsigned long)sdata->data;
> > +
> > + if (flags == BPF_LOCAL_STORAGE_GET_F_CREATE &&
> > + atomic_inc_not_zero(&inode->i_count)) {
> > + sdata = inode_storage_update(inode, map, value, BPF_NOEXIST);
> > + iput(inode);
> > + return IS_ERR(sdata) ?
> > + (unsigned long)NULL : (unsigned long)sdata->data;
> > + }
>
> This is wrong. You cannot just copy paste the refcounting logic
> from bpf_sk_storage_get(). sk->sk_refcnt is very different from inode->i_count.
> To start, the inode->i_count cannot be incremented without lock.
Good catch! Agreed, Jann pointed out that this can lead to bugs
similar to https://crbug.com/project-zero/2015.
> If you really need to do it you need igrab().
> Secondly, the iput() is not possible to call from bpf prog yet, since
> progs are not sleepable and iput() may call iput_final() which may sleep.
Agreed, I will send a separate patch to add a might_sleep call to
iput() which currently only has a "Consequently, iput() can sleep."
warning in the comments so that this can be caught by
CONFIG_DEBUG_ATOMIC_SLEEP.
> But considering that only lsm progs from lsm hooks will call bpf_inode_storage_get()
> the inode is not going to disappear while this function is running.
If the inode pointer is an argument to the LSM hook, it won't
disappear and yes this does hold generally true for the other
use-cases as well.
> So why touch i_count ?
>
> > +
> > + return (unsigned long)NULL;
> > +}
> > +
> > BPF_CALL_2(bpf_sk_storage_delete, struct bpf_map *, map, struct sock *, sk)
> > {
> > if (refcount_inc_not_zero(&sk->sk_refcnt)) {
> > @@ -957,6 +1229,20 @@ BPF_CALL_2(bpf_sk_storage_delete, struct bpf_map *, map, struct sock *, sk)
> > return -ENOENT;
> > }
> >
> > +BPF_CALL_2(bpf_inode_storage_delete,
> > + struct bpf_map *, map, struct inode *, inode)
> > +{
> > + int err;
> > +
> > + if (atomic_inc_not_zero(&inode->i_count)) {
> > + err = inode_storage_delete(inode, map);
> > + iput(inode);
> > + return err;
> > + }
>
> ditto.
>
> > +
> > + return inode_storage_delete(inode, map);
>
> bad copy-paste from bpf_sk_storage_delete?
> or what is this logic suppose to do?
The former :) fixed...
- KP
next prev parent reply other threads:[~2020-05-27 2:11 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-26 16:33 [PATCH bpf-next 0/4] Generalizing bpf_local_storage KP Singh
2020-05-26 16:33 ` [PATCH bpf-next 1/4] bpf: Generalize bpf_sk_storage KP Singh
2020-05-27 22:06 ` kbuild test robot
2020-05-26 16:33 ` [PATCH bpf-next 2/4] bpf: Implement bpf_local_storage for inodes KP Singh
2020-05-27 0:49 ` Alexei Starovoitov
2020-05-27 2:11 ` KP Singh [this message]
2020-05-27 5:08 ` Christoph Hellwig
2020-05-27 12:38 ` KP Singh
2020-05-27 16:41 ` Casey Schaufler
2020-05-27 17:09 ` KP Singh
2020-06-02 21:35 ` kbuild test robot
2020-05-26 16:33 ` [PATCH bpf-next 3/4] bpf: Allow local storage to be used from LSM programs KP Singh
2020-05-26 16:33 ` [PATCH bpf-next 4/4] bpf: Add selftests for local_storage KP Singh
2020-06-01 20:29 ` Andrii Nakryiko
2020-06-16 15:54 ` KP Singh
2020-06-16 19:25 ` Andrii Nakryiko
2020-06-16 20:40 ` Yonghong Song
2020-06-17 19:19 ` Yonghong Song
2020-06-17 19:26 ` KP Singh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200527021111.GA197666@google.com \
--to=kpsingh@chromium.org \
--cc=alexei.starovoitov@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=jannh@google.com \
--cc=jmorris@namei.org \
--cc=kafai@fb.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=revest@chromium.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).