* [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt
@ 2021-09-23 20:09 Daniel Borkmann
2021-09-23 20:09 ` [PATCH bpf 2/2] bpf, test, cgroup: Use sk_{alloc,free} for test cases Daniel Borkmann
2021-09-24 17:21 ` [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt Tejun Heo
0 siblings, 2 replies; 4+ messages in thread
From: Daniel Borkmann @ 2021-09-23 20:09 UTC (permalink / raw)
To: alexei.starovoitov
Cc: andrii, bpf, Daniel Borkmann, syzbot+df709157a4ecaf192b03,
Tejun Heo, Stanislav Fomichev
If cgroup_sk_alloc() is called from interrupt context, then just assign the
root cgroup to skcd->cgroup. Prior to commit 8520e224f547 ("bpf, cgroups:
Fix cgroup v2 fallback on v1/v2 mixed mode") we would just return, and later
on in sock_cgroup_ptr(), we were NULL-testing the cgroup in fast-path. Rather
than re-adding the NULL-test to the fast-path we can just assign it once from
cgroup_sk_alloc() given v1/v2 handling has been simplified.
Fixes: 8520e224f547 ("bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode")
Reported-by: syzbot+df709157a4ecaf192b03@syzkaller.appspotmail.com
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: syzbot+df709157a4ecaf192b03@syzkaller.appspotmail.com
Cc: Tejun Heo <tj@kernel.org>
Cc: Stanislav Fomichev <sdf@google.com>
---
kernel/cgroup/cgroup.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 8afa8690d288..570b0c97392a 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -6574,22 +6574,29 @@ int cgroup_parse_float(const char *input, unsigned dec_shift, s64 *v)
void cgroup_sk_alloc(struct sock_cgroup_data *skcd)
{
- /* Don't associate the sock with unrelated interrupted task's cgroup. */
- if (in_interrupt())
- return;
+ struct cgroup *cgroup;
rcu_read_lock();
+ /* Don't associate the sock with unrelated interrupted task's cgroup. */
+ if (in_interrupt()) {
+ cgroup = &cgrp_dfl_root.cgrp;
+ cgroup_get(cgroup);
+ goto out;
+ }
+
while (true) {
struct css_set *cset;
cset = task_css_set(current);
if (likely(cgroup_tryget(cset->dfl_cgrp))) {
- skcd->cgroup = cset->dfl_cgrp;
- cgroup_bpf_get(cset->dfl_cgrp);
+ cgroup = cset->dfl_cgrp;
break;
}
cpu_relax();
}
+out:
+ skcd->cgroup = cgroup;
+ cgroup_bpf_get(cgroup);
rcu_read_unlock();
}
--
2.21.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH bpf 2/2] bpf, test, cgroup: Use sk_{alloc,free} for test cases
2021-09-23 20:09 [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt Daniel Borkmann
@ 2021-09-23 20:09 ` Daniel Borkmann
2021-09-24 17:21 ` [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt Tejun Heo
1 sibling, 0 replies; 4+ messages in thread
From: Daniel Borkmann @ 2021-09-23 20:09 UTC (permalink / raw)
To: alexei.starovoitov
Cc: andrii, bpf, Daniel Borkmann, syzbot+664b58e9a40fbb2cec71,
syzbot+33f36d0754d4c5c0e102, Stanislav Fomichev,
Martin KaFai Lau, Song Liu
BPF test infra has some hacks in place which kzalloc() a socket and perform
minimum init via sock_net_set() and sock_init_data(). As a result, the sk's
skcd->cgroup is NULL since it didn't go through proper initialization as it
would have been the case from sk_alloc(). Rather than re-adding a NULL test
in sock_cgroup_ptr() just for this, use sk_{alloc,free}() pair for the test
socket. The latter also allows to get rid of the bpf_sk_storage_free() special
case.
Fixes: 8520e224f547 ("bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode")
Fixes: b7a1848e8398 ("bpf: add BPF_PROG_TEST_RUN support for flow dissector")
Fixes: 2cb494a36c98 ("bpf: add tests for direct packet access from CGROUP_SKB")
Reported-by: syzbot+664b58e9a40fbb2cec71@syzkaller.appspotmail.com
Reported-by: syzbot+33f36d0754d4c5c0e102@syzkaller.appspotmail.com
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: syzbot+664b58e9a40fbb2cec71@syzkaller.appspotmail.com
Tested-by: syzbot+33f36d0754d4c5c0e102@syzkaller.appspotmail.com
Cc: Stanislav Fomichev <sdf@google.com>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Song Liu <songliubraving@fb.com>
---
net/bpf/test_run.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 2eb0e55ef54d..b5f4ef35357c 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -552,6 +552,12 @@ static void convert_skb_to___skb(struct sk_buff *skb, struct __sk_buff *__skb)
__skb->gso_segs = skb_shinfo(skb)->gso_segs;
}
+static struct proto bpf_dummy_proto = {
+ .name = "bpf_dummy",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct sock),
+};
+
int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
union bpf_attr __user *uattr)
{
@@ -596,20 +602,19 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
break;
}
- sk = kzalloc(sizeof(struct sock), GFP_USER);
+ sk = sk_alloc(net, AF_UNSPEC, GFP_USER, &bpf_dummy_proto, 1);
if (!sk) {
kfree(data);
kfree(ctx);
return -ENOMEM;
}
- sock_net_set(sk, net);
sock_init_data(NULL, sk);
skb = build_skb(data, 0);
if (!skb) {
kfree(data);
kfree(ctx);
- kfree(sk);
+ sk_free(sk);
return -ENOMEM;
}
skb->sk = sk;
@@ -682,8 +687,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
if (dev && dev != net->loopback_dev)
dev_put(dev);
kfree_skb(skb);
- bpf_sk_storage_free(sk);
- kfree(sk);
+ sk_free(sk);
kfree(ctx);
return ret;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt
2021-09-23 20:09 [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt Daniel Borkmann
2021-09-23 20:09 ` [PATCH bpf 2/2] bpf, test, cgroup: Use sk_{alloc,free} for test cases Daniel Borkmann
@ 2021-09-24 17:21 ` Tejun Heo
2021-09-24 21:20 ` Daniel Borkmann
1 sibling, 1 reply; 4+ messages in thread
From: Tejun Heo @ 2021-09-24 17:21 UTC (permalink / raw)
To: Daniel Borkmann
Cc: alexei.starovoitov, andrii, bpf, syzbot+df709157a4ecaf192b03,
Stanislav Fomichev
On Thu, Sep 23, 2021 at 10:09:23PM +0200, Daniel Borkmann wrote:
> If cgroup_sk_alloc() is called from interrupt context, then just assign the
> root cgroup to skcd->cgroup. Prior to commit 8520e224f547 ("bpf, cgroups:
> Fix cgroup v2 fallback on v1/v2 mixed mode") we would just return, and later
> on in sock_cgroup_ptr(), we were NULL-testing the cgroup in fast-path. Rather
> than re-adding the NULL-test to the fast-path we can just assign it once from
> cgroup_sk_alloc() given v1/v2 handling has been simplified.
I think you should explain why this is safe - ie. when do we hit the
condition and leak the socket to the root cgroup and why is that okay?
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt
2021-09-24 17:21 ` [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt Tejun Heo
@ 2021-09-24 21:20 ` Daniel Borkmann
0 siblings, 0 replies; 4+ messages in thread
From: Daniel Borkmann @ 2021-09-24 21:20 UTC (permalink / raw)
To: Tejun Heo
Cc: alexei.starovoitov, andrii, bpf, syzbot+df709157a4ecaf192b03,
Stanislav Fomichev
On 9/24/21 7:21 PM, Tejun Heo wrote:
> On Thu, Sep 23, 2021 at 10:09:23PM +0200, Daniel Borkmann wrote:
>> If cgroup_sk_alloc() is called from interrupt context, then just assign the
>> root cgroup to skcd->cgroup. Prior to commit 8520e224f547 ("bpf, cgroups:
>> Fix cgroup v2 fallback on v1/v2 mixed mode") we would just return, and later
>> on in sock_cgroup_ptr(), we were NULL-testing the cgroup in fast-path. Rather
>> than re-adding the NULL-test to the fast-path we can just assign it once from
>> cgroup_sk_alloc() given v1/v2 handling has been simplified.
>
> I think you should explain why this is safe - ie. when do we hit the
> condition and leak the socket to the root cgroup and why is that okay?
I'll add it to the commit log. What I was trying to say is that before the
8520e224f547 fix, the cgroup_sk_alloc() would bail out and return early when
in_interrupt(), and in that case skcd->cgroup remained NULL. sock_cgroup_ptr()
had a NULL check for it in the old code where it says 'v ?: &cgrp_dfl_root.cgrp'
and I wonder given the !CONFIG_CGROUP_NET_PRIO && !CONFIG_CGROUP_NET_CLASSID
path doesn't have it, whether syzbot never tripped over it because it was not
testing with such config. From the repro [0], this is specific to old netrom
legacy code where RX handler nr_rx_frame() calls nr_make_new() which calls
sk_alloc() and therefore cgroup_sk_alloc() with in_interrupt() condition. Thus
the NULL skcd->cgroup, where it trips over on cgroup_sk_free() side [1]. I'm
certain you hit the same in netrom with mentioned configs off.
Thanks,
Daniel
[0] https://syzkaller.appspot.com/x/repro.syz?x=12f2b28d300000
[1] https://lkml.org/lkml/2021/9/17/1041
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-09-24 21:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-23 20:09 [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt Daniel Borkmann
2021-09-23 20:09 ` [PATCH bpf 2/2] bpf, test, cgroup: Use sk_{alloc,free} for test cases Daniel Borkmann
2021-09-24 17:21 ` [PATCH bpf 1/2] bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt Tejun Heo
2021-09-24 21:20 ` Daniel Borkmann
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.