Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched_ext: Drop TRACING access to select_cpu kfuncs

The select_cpu kfuncs - scx_bpf_select_cpu_dfl(), scx_bpf_select_cpu_and()
and __scx_bpf_select_cpu_and() - take task_rq_lock() internally. Exposing
them via scx_kfunc_set_idle to BPF_PROG_TYPE_TRACING is unsafe: arbitrary
tracing contexts (kprobes, tracepoints, fentry, LSM) may run with @p's
pi_lock state unknown.

Move them out of scx_kfunc_ids_idle into a new scx_kfunc_ids_select_cpu
set registered only for STRUCT_OPS and SYSCALL.

Extracted from a larger verifier-time kfunc context filter patch
originally written by Juntong Deng.

Original-patch-by: Juntong Deng <juntong.deng@outlook.com>
Cc: Cheng-Yang Chou <yphbchou0911@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Andrea Righi <arighi@nvidia.com>

Tejun Heo 9b5501d3 dcd47f27

+21 -4
+21 -4
kernel/sched/ext_idle.c
··· 1469 1469 BTF_ID_FLAGS(func, scx_bpf_pick_idle_cpu, KF_IMPLICIT_ARGS | KF_RCU) 1470 1470 BTF_ID_FLAGS(func, scx_bpf_pick_any_cpu_node, KF_IMPLICIT_ARGS | KF_RCU) 1471 1471 BTF_ID_FLAGS(func, scx_bpf_pick_any_cpu, KF_IMPLICIT_ARGS | KF_RCU) 1472 - BTF_ID_FLAGS(func, __scx_bpf_select_cpu_and, KF_IMPLICIT_ARGS | KF_RCU) 1473 - BTF_ID_FLAGS(func, scx_bpf_select_cpu_and, KF_RCU) 1474 - BTF_ID_FLAGS(func, scx_bpf_select_cpu_dfl, KF_IMPLICIT_ARGS | KF_RCU) 1475 1472 BTF_KFUNCS_END(scx_kfunc_ids_idle) 1476 1473 1477 1474 static const struct btf_kfunc_id_set scx_kfunc_set_idle = { 1478 1475 .owner = THIS_MODULE, 1479 1476 .set = &scx_kfunc_ids_idle, 1477 + }; 1478 + 1479 + /* 1480 + * The select_cpu kfuncs internally call task_rq_lock() when invoked from an 1481 + * rq-unlocked context, and thus cannot be safely called from arbitrary tracing 1482 + * contexts where @p's pi_lock state is unknown. Keep them out of 1483 + * BPF_PROG_TYPE_TRACING by registering them in their own set which is exposed 1484 + * only to STRUCT_OPS and SYSCALL programs. 1485 + */ 1486 + BTF_KFUNCS_START(scx_kfunc_ids_select_cpu) 1487 + BTF_ID_FLAGS(func, __scx_bpf_select_cpu_and, KF_IMPLICIT_ARGS | KF_RCU) 1488 + BTF_ID_FLAGS(func, scx_bpf_select_cpu_and, KF_RCU) 1489 + BTF_ID_FLAGS(func, scx_bpf_select_cpu_dfl, KF_IMPLICIT_ARGS | KF_RCU) 1490 + BTF_KFUNCS_END(scx_kfunc_ids_select_cpu) 1491 + 1492 + static const struct btf_kfunc_id_set scx_kfunc_set_select_cpu = { 1493 + .owner = THIS_MODULE, 1494 + .set = &scx_kfunc_ids_select_cpu, 1480 1495 }; 1481 1496 1482 1497 int scx_idle_init(void) ··· 1500 1485 1501 1486 ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &scx_kfunc_set_idle) || 1502 1487 register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &scx_kfunc_set_idle) || 1503 - register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &scx_kfunc_set_idle); 1488 + register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &scx_kfunc_set_idle) || 1489 + register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &scx_kfunc_set_select_cpu) || 1490 + register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &scx_kfunc_set_select_cpu); 1504 1491 1505 1492 return ret; 1506 1493 }