Skip to content

Commit 76bcf06

Browse files
borkmannintel-lab-lkp
authored andcommitted
bpf: enable bpf cgroup hooks to retrieve cgroup v2 and ancestor id
Enable the bpf_get_current_cgroup_id() helper for connect(), sendmsg(), recvmsg() and bind-related hooks in order to retrieve the cgroup v2 context which can then be used as part of the key for BPF map lookups, for example. Given these hooks operate in process context 'current' is always valid and pointing to the app that is performing mentioned syscalls if it's subject to a v2 cgroup. Also with same motivation of commit 7723628 ("bpf: Introduce bpf_skb_ancestor_cgroup_id helper") enable retrieval of ancestor from current so the cgroup id can be used for policy lookups which can then forbid connect() / bind(), for example. Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 1c869ef commit 76bcf06

File tree

6 files changed

+72
-2
lines changed

6 files changed

+72
-2
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,7 @@ extern const struct bpf_func_proto bpf_get_stack_proto;
15011501
extern const struct bpf_func_proto bpf_sock_map_update_proto;
15021502
extern const struct bpf_func_proto bpf_sock_hash_update_proto;
15031503
extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto;
1504+
extern const struct bpf_func_proto bpf_get_current_ancestor_cgroup_id_proto;
15041505
extern const struct bpf_func_proto bpf_msg_redirect_hash_proto;
15051506
extern const struct bpf_func_proto bpf_msg_redirect_map_proto;
15061507
extern const struct bpf_func_proto bpf_sk_redirect_hash_proto;

include/uapi/linux/bpf.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2963,6 +2963,24 @@ union bpf_attr {
29632963
* instead of sockets.
29642964
* Return
29652965
* A 8-byte long opaque number.
2966+
*
2967+
* u64 bpf_get_current_ancestor_cgroup_id(int ancestor_level)
2968+
* Description
2969+
* Return id of cgroup v2 that is ancestor of the cgroup associated
2970+
* with the current task at the *ancestor_level*. The root cgroup
2971+
* is at *ancestor_level* zero and each step down the hierarchy
2972+
* increments the level. If *ancestor_level* == level of cgroup
2973+
* associated with the current task, then return value will be the
2974+
* same as that of **bpf_get_current_cgroup_id**\ ().
2975+
*
2976+
* The helper is useful to implement policies based on cgroups
2977+
* that are upper in hierarchy than immediate cgroup associated
2978+
* with the current task.
2979+
*
2980+
* The format of returned id and helper limitations are same as in
2981+
* **bpf_get_current_cgroup_id**\ ().
2982+
* Return
2983+
* The id is returned or 0 in case the id could not be retrieved.
29662984
*/
29672985
#define __BPF_FUNC_MAPPER(FN) \
29682986
FN(unspec), \
@@ -3087,7 +3105,8 @@ union bpf_attr {
30873105
FN(read_branch_records), \
30883106
FN(get_ns_current_pid_tgid), \
30893107
FN(xdp_output), \
3090-
FN(get_netns_cookie),
3108+
FN(get_netns_cookie), \
3109+
FN(get_current_ancestor_cgroup_id),
30913110

30923111
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
30933112
* function eBPF program intends to call

kernel/bpf/core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,6 +2156,7 @@ const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
21562156
const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
21572157
const struct bpf_func_proto bpf_get_current_comm_proto __weak;
21582158
const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
2159+
const struct bpf_func_proto bpf_get_current_ancestor_cgroup_id_proto __weak;
21592160
const struct bpf_func_proto bpf_get_local_storage_proto __weak;
21602161
const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto __weak;
21612162

kernel/bpf/helpers.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,24 @@ const struct bpf_func_proto bpf_get_current_cgroup_id_proto = {
340340
.ret_type = RET_INTEGER,
341341
};
342342

343+
BPF_CALL_1(bpf_get_current_ancestor_cgroup_id, int, ancestor_level)
344+
{
345+
struct cgroup *cgrp = task_dfl_cgroup(current);
346+
struct cgroup *ancestor;
347+
348+
ancestor = cgroup_ancestor(cgrp, ancestor_level);
349+
if (!ancestor)
350+
return 0;
351+
return cgroup_id(ancestor);
352+
}
353+
354+
const struct bpf_func_proto bpf_get_current_ancestor_cgroup_id_proto = {
355+
.func = bpf_get_current_ancestor_cgroup_id,
356+
.gpl_only = false,
357+
.ret_type = RET_INTEGER,
358+
.arg1_type = ARG_ANYTHING,
359+
};
360+
343361
#ifdef CONFIG_CGROUP_BPF
344362
DECLARE_PER_CPU(struct bpf_cgroup_storage*,
345363
bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);

net/core/filter.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6018,6 +6018,12 @@ sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
60186018
return &bpf_get_netns_cookie_sock_proto;
60196019
case BPF_FUNC_perf_event_output:
60206020
return &bpf_event_output_data_proto;
6021+
#ifdef CONFIG_CGROUPS
6022+
case BPF_FUNC_get_current_cgroup_id:
6023+
return &bpf_get_current_cgroup_id_proto;
6024+
case BPF_FUNC_get_current_ancestor_cgroup_id:
6025+
return &bpf_get_current_ancestor_cgroup_id_proto;
6026+
#endif
60216027
#ifdef CONFIG_CGROUP_NET_CLASSID
60226028
case BPF_FUNC_get_cgroup_classid:
60236029
return &bpf_get_cgroup_classid_curr_proto;
@@ -6052,6 +6058,12 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
60526058
return &bpf_get_local_storage_proto;
60536059
case BPF_FUNC_perf_event_output:
60546060
return &bpf_event_output_data_proto;
6061+
#ifdef CONFIG_CGROUPS
6062+
case BPF_FUNC_get_current_cgroup_id:
6063+
return &bpf_get_current_cgroup_id_proto;
6064+
case BPF_FUNC_get_current_ancestor_cgroup_id:
6065+
return &bpf_get_current_ancestor_cgroup_id_proto;
6066+
#endif
60556067
#ifdef CONFIG_CGROUP_NET_CLASSID
60566068
case BPF_FUNC_get_cgroup_classid:
60576069
return &bpf_get_cgroup_classid_curr_proto;

tools/include/uapi/linux/bpf.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2963,6 +2963,24 @@ union bpf_attr {
29632963
* instead of sockets.
29642964
* Return
29652965
* A 8-byte long opaque number.
2966+
*
2967+
* u64 bpf_get_current_ancestor_cgroup_id(int ancestor_level)
2968+
* Description
2969+
* Return id of cgroup v2 that is ancestor of the cgroup associated
2970+
* with the current task at the *ancestor_level*. The root cgroup
2971+
* is at *ancestor_level* zero and each step down the hierarchy
2972+
* increments the level. If *ancestor_level* == level of cgroup
2973+
* associated with the current task, then return value will be the
2974+
* same as that of **bpf_get_current_cgroup_id**\ ().
2975+
*
2976+
* The helper is useful to implement policies based on cgroups
2977+
* that are upper in hierarchy than immediate cgroup associated
2978+
* with the current task.
2979+
*
2980+
* The format of returned id and helper limitations are same as in
2981+
* **bpf_get_current_cgroup_id**\ ().
2982+
* Return
2983+
* The id is returned or 0 in case the id could not be retrieved.
29662984
*/
29672985
#define __BPF_FUNC_MAPPER(FN) \
29682986
FN(unspec), \
@@ -3087,7 +3105,8 @@ union bpf_attr {
30873105
FN(read_branch_records), \
30883106
FN(get_ns_current_pid_tgid), \
30893107
FN(xdp_output), \
3090-
FN(get_netns_cookie),
3108+
FN(get_netns_cookie), \
3109+
FN(get_current_ancestor_cgroup_id),
30913110

30923111
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
30933112
* function eBPF program intends to call

0 commit comments

Comments
 (0)