diff options
Diffstat (limited to 'kernel/bpf/cgroup.c')
-rw-r--r-- | kernel/bpf/cgroup.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 6b7500bbdb53..e88abc0865d5 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c | |||
@@ -384,6 +384,52 @@ cleanup: | |||
384 | return err; | 384 | return err; |
385 | } | 385 | } |
386 | 386 | ||
387 | /* Must be called with cgroup_mutex held to avoid races. */ | ||
388 | int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, | ||
389 | union bpf_attr __user *uattr) | ||
390 | { | ||
391 | __u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids); | ||
392 | enum bpf_attach_type type = attr->query.attach_type; | ||
393 | struct list_head *progs = &cgrp->bpf.progs[type]; | ||
394 | u32 flags = cgrp->bpf.flags[type]; | ||
395 | int cnt, ret = 0, i; | ||
396 | |||
397 | if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) | ||
398 | cnt = bpf_prog_array_length(cgrp->bpf.effective[type]); | ||
399 | else | ||
400 | cnt = prog_list_length(progs); | ||
401 | |||
402 | if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags))) | ||
403 | return -EFAULT; | ||
404 | if (copy_to_user(&uattr->query.prog_cnt, &cnt, sizeof(cnt))) | ||
405 | return -EFAULT; | ||
406 | if (attr->query.prog_cnt == 0 || !prog_ids || !cnt) | ||
407 | /* return early if user requested only program count + flags */ | ||
408 | return 0; | ||
409 | if (attr->query.prog_cnt < cnt) { | ||
410 | cnt = attr->query.prog_cnt; | ||
411 | ret = -ENOSPC; | ||
412 | } | ||
413 | |||
414 | if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) { | ||
415 | return bpf_prog_array_copy_to_user(cgrp->bpf.effective[type], | ||
416 | prog_ids, cnt); | ||
417 | } else { | ||
418 | struct bpf_prog_list *pl; | ||
419 | u32 id; | ||
420 | |||
421 | i = 0; | ||
422 | list_for_each_entry(pl, progs, node) { | ||
423 | id = pl->prog->aux->id; | ||
424 | if (copy_to_user(prog_ids + i, &id, sizeof(id))) | ||
425 | return -EFAULT; | ||
426 | if (++i == cnt) | ||
427 | break; | ||
428 | } | ||
429 | } | ||
430 | return ret; | ||
431 | } | ||
432 | |||
387 | /** | 433 | /** |
388 | * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering | 434 | * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering |
389 | * @sk: The socket sending or receiving traffic | 435 | * @sk: The socket sending or receiving traffic |