bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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 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).