Skip to content

Commit 0e426a3

Browse files
Pu LehuiMartin KaFai Lau
authored andcommitted
bpf, cgroup: Reject prog_attach_flags array when effective query
Attach flags is only valid for attached progs of this layer cgroup, but not for effective progs. For querying with EFFECTIVE flags, exporting attach flags does not make sense. So when effective query, we reject prog_attach_flags array and don't need to populate it. Also we limit attach_flags to output 0 during effective query. Fixes: b79c9fc ("bpf: implement BPF_PROG_QUERY for BPF_LSM_CGROUP") Signed-off-by: Pu Lehui <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin KaFai Lau <[email protected]>
1 parent 83c10cc commit 0e426a3

File tree

3 files changed

+28
-14
lines changed

3 files changed

+28
-14
lines changed

include/uapi/linux/bpf.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@ enum {
12331233

12341234
/* Query effective (directly attached + inherited from ancestor cgroups)
12351235
* programs that will be executed for events within a cgroup.
1236-
* attach_flags with this flag are returned only for directly attached programs.
1236+
* attach_flags with this flag are always returned 0.
12371237
*/
12381238
#define BPF_F_QUERY_EFFECTIVE (1U << 0)
12391239

@@ -1432,7 +1432,10 @@ union bpf_attr {
14321432
__u32 attach_flags;
14331433
__aligned_u64 prog_ids;
14341434
__u32 prog_cnt;
1435-
__aligned_u64 prog_attach_flags; /* output: per-program attach_flags */
1435+
/* output: per-program attach_flags.
1436+
* not allowed to be set during effective query.
1437+
*/
1438+
__aligned_u64 prog_attach_flags;
14361439
} query;
14371440

14381441
struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */

kernel/bpf/cgroup.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
10201020
union bpf_attr __user *uattr)
10211021
{
10221022
__u32 __user *prog_attach_flags = u64_to_user_ptr(attr->query.prog_attach_flags);
1023+
bool effective_query = attr->query.query_flags & BPF_F_QUERY_EFFECTIVE;
10231024
__u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
10241025
enum bpf_attach_type type = attr->query.attach_type;
10251026
enum cgroup_bpf_attach_type from_atype, to_atype;
@@ -1029,8 +1030,12 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
10291030
int total_cnt = 0;
10301031
u32 flags;
10311032

1033+
if (effective_query && prog_attach_flags)
1034+
return -EINVAL;
1035+
10321036
if (type == BPF_LSM_CGROUP) {
1033-
if (attr->query.prog_cnt && prog_ids && !prog_attach_flags)
1037+
if (!effective_query && attr->query.prog_cnt &&
1038+
prog_ids && !prog_attach_flags)
10341039
return -EINVAL;
10351040

10361041
from_atype = CGROUP_LSM_START;
@@ -1045,7 +1050,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
10451050
}
10461051

10471052
for (atype = from_atype; atype <= to_atype; atype++) {
1048-
if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) {
1053+
if (effective_query) {
10491054
effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
10501055
lockdep_is_held(&cgroup_mutex));
10511056
total_cnt += bpf_prog_array_length(effective);
@@ -1054,6 +1059,8 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
10541059
}
10551060
}
10561061

1062+
/* always output uattr->query.attach_flags as 0 during effective query */
1063+
flags = effective_query ? 0 : flags;
10571064
if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
10581065
return -EFAULT;
10591066
if (copy_to_user(&uattr->query.prog_cnt, &total_cnt, sizeof(total_cnt)))
@@ -1068,7 +1075,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
10681075
}
10691076

10701077
for (atype = from_atype; atype <= to_atype && total_cnt; atype++) {
1071-
if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) {
1078+
if (effective_query) {
10721079
effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
10731080
lockdep_is_held(&cgroup_mutex));
10741081
cnt = min_t(int, bpf_prog_array_length(effective), total_cnt);
@@ -1090,15 +1097,16 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
10901097
if (++i == cnt)
10911098
break;
10921099
}
1093-
}
10941100

1095-
if (prog_attach_flags) {
1096-
flags = cgrp->bpf.flags[atype];
1101+
if (prog_attach_flags) {
1102+
flags = cgrp->bpf.flags[atype];
10971103

1098-
for (i = 0; i < cnt; i++)
1099-
if (copy_to_user(prog_attach_flags + i, &flags, sizeof(flags)))
1100-
return -EFAULT;
1101-
prog_attach_flags += cnt;
1104+
for (i = 0; i < cnt; i++)
1105+
if (copy_to_user(prog_attach_flags + i,
1106+
&flags, sizeof(flags)))
1107+
return -EFAULT;
1108+
prog_attach_flags += cnt;
1109+
}
11021110
}
11031111

11041112
prog_ids += cnt;

tools/include/uapi/linux/bpf.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@ enum {
12331233

12341234
/* Query effective (directly attached + inherited from ancestor cgroups)
12351235
* programs that will be executed for events within a cgroup.
1236-
* attach_flags with this flag are returned only for directly attached programs.
1236+
* attach_flags with this flag are always returned 0.
12371237
*/
12381238
#define BPF_F_QUERY_EFFECTIVE (1U << 0)
12391239

@@ -1432,7 +1432,10 @@ union bpf_attr {
14321432
__u32 attach_flags;
14331433
__aligned_u64 prog_ids;
14341434
__u32 prog_cnt;
1435-
__aligned_u64 prog_attach_flags; /* output: per-program attach_flags */
1435+
/* output: per-program attach_flags.
1436+
* not allowed to be set during effective query.
1437+
*/
1438+
__aligned_u64 prog_attach_flags;
14361439
} query;
14371440

14381441
struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */

0 commit comments

Comments
 (0)