Skip to content

Commit 60d20f9

Browse files
sargundavem330
authored andcommitted
bpf: Add bpf_current_task_under_cgroup helper
This adds a bpf helper that's similar to the skb_in_cgroup helper to check whether the probe is currently executing in the context of a specific subset of the cgroupsv2 hierarchy. It does this based on membership test for a cgroup arraymap. It is invalid to call this in an interrupt, and it'll return an error. The helper is primarily to be used in debugging activities for containers, where you may have multiple programs running in a given top-level "container". Signed-off-by: Sargun Dhillon <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Daniel Borkmann <[email protected]> Cc: Tejun Heo <[email protected]> Acked-by: Tejun Heo <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent aed704b commit 60d20f9

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

include/uapi/linux/bpf.h

+11
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,17 @@ enum bpf_func_id {
375375
*/
376376
BPF_FUNC_probe_write_user,
377377

378+
/**
379+
* bpf_current_task_under_cgroup(map, index) - Check cgroup2 membership of current task
380+
* @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type
381+
* @index: index of the cgroup in the bpf_map
382+
* Return:
383+
* == 0 current failed the cgroup2 descendant test
384+
* == 1 current succeeded the cgroup2 descendant test
385+
* < 0 error
386+
*/
387+
BPF_FUNC_current_task_under_cgroup,
388+
378389
__BPF_FUNC_MAX_ID,
379390
};
380391

kernel/bpf/arraymap.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ static int __init register_perf_event_array_map(void)
538538
}
539539
late_initcall(register_perf_event_array_map);
540540

541-
#ifdef CONFIG_SOCK_CGROUP_DATA
541+
#ifdef CONFIG_CGROUPS
542542
static void *cgroup_fd_array_get_ptr(struct bpf_map *map,
543543
struct file *map_file /* not used */,
544544
int fd)

kernel/bpf/verifier.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,8 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)
10531053
goto error;
10541054
break;
10551055
case BPF_MAP_TYPE_CGROUP_ARRAY:
1056-
if (func_id != BPF_FUNC_skb_in_cgroup)
1056+
if (func_id != BPF_FUNC_skb_in_cgroup &&
1057+
func_id != BPF_FUNC_current_task_under_cgroup)
10571058
goto error;
10581059
break;
10591060
default:
@@ -1075,6 +1076,7 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)
10751076
if (map->map_type != BPF_MAP_TYPE_STACK_TRACE)
10761077
goto error;
10771078
break;
1079+
case BPF_FUNC_current_task_under_cgroup:
10781080
case BPF_FUNC_skb_in_cgroup:
10791081
if (map->map_type != BPF_MAP_TYPE_CGROUP_ARRAY)
10801082
goto error;

kernel/trace/bpf_trace.c

+30
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,34 @@ static const struct bpf_func_proto bpf_get_current_task_proto = {
376376
.ret_type = RET_INTEGER,
377377
};
378378

379+
static u64 bpf_current_task_under_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
380+
{
381+
struct bpf_map *map = (struct bpf_map *)(long)r1;
382+
struct bpf_array *array = container_of(map, struct bpf_array, map);
383+
struct cgroup *cgrp;
384+
u32 idx = (u32)r2;
385+
386+
if (unlikely(in_interrupt()))
387+
return -EINVAL;
388+
389+
if (unlikely(idx >= array->map.max_entries))
390+
return -E2BIG;
391+
392+
cgrp = READ_ONCE(array->ptrs[idx]);
393+
if (unlikely(!cgrp))
394+
return -EAGAIN;
395+
396+
return task_under_cgroup_hierarchy(current, cgrp);
397+
}
398+
399+
static const struct bpf_func_proto bpf_current_task_under_cgroup_proto = {
400+
.func = bpf_current_task_under_cgroup,
401+
.gpl_only = false,
402+
.ret_type = RET_INTEGER,
403+
.arg1_type = ARG_CONST_MAP_PTR,
404+
.arg2_type = ARG_ANYTHING,
405+
};
406+
379407
static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id)
380408
{
381409
switch (func_id) {
@@ -407,6 +435,8 @@ static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id)
407435
return &bpf_perf_event_read_proto;
408436
case BPF_FUNC_probe_write_user:
409437
return bpf_get_probe_write_proto();
438+
case BPF_FUNC_current_task_under_cgroup:
439+
return &bpf_current_task_under_cgroup_proto;
410440
default:
411441
return NULL;
412442
}

0 commit comments

Comments
 (0)