sched discussion
[PATCH v4] security: Expand task_setscheduler LSM hook
LLM 分析
Scheduler 子系统:扩展 task_setscheduler LSM 钩子,把 cpumask 透出给 LSM
系列概况
- 标题:
[PATCH v4] security: Expand task_setscheduler LSM hook - 作者:Aaron Tomlin
<atomlin@atomlin.com> - 版本:v4(lore 中还能看到更早的 v1/v2/v3 Message-ID)
- 规模:单 patch,跨 10 个文件,约 25 行净增
- 修改文件:
arch/mips/kernel/mips-mt-fpaff.c、fs/proc/base.c、include/linux/lsm_hook_defs.h、include/linux/security.h、kernel/cgroup/cpuset.c、kernel/sched/sycalls.c、security/commoncap.c、security/security.c、security/selinux/hooks.c、security/smack/smack_lsm.c - 代码统计:9 个直接修改点,每个 hunk 都很小;改动集中在钩子签名 + 调用点同步
- Message-ID:
20260720014156.459386-1-atomlin@atomlin.com - 完整性:v4 邮件正文完整;Casey Schaufler 与 Aaron Tomlin 8 月两封回复在 lore 抓取里被截断,只看到引文前缀
补丁目的
让 LSM 在 sched_setaffinity()、cpuset attach、mipsmt FP affinity 这些"把任务拉到一组 CPU"的路径里,能拿到目标 cpumask,从而做空间隔离 (spatial isolation) 策略。原钩子只能拿到 sched_attr,对 affinity 请求完全"失明"。
旧流程的问题
sched_setaffinity()走 affinity 路径,但security_task_setscheduler(p)只有一个参数,LSM 看不到in_mask- 多租户 / 实时环境无法审计或拦截把任务绑到加密核 / 隔离核的请求
- cpuset attach 把任务拖到新 CPU 集合上时,也没有 LSM 决策点
新流程
- 钩子扩展为
task_setscheduler(p, attr, in_mask),attr与in_mask都标__nullable - 不涉及亲和性的调用点显式传 NULL(
__sched_setscheduler的 policy/param 路径、timerslack_ns_write) - 涉及亲和性的调用点把真实 mask 透传:
sched_setaffinity、mipsmt_sys_sched_setaffinity、cpuset_can_attach、cpuset_can_fork
Patch 概览
10 个文件、9 个直接修改点,全部围绕"加两个参数并同步所有调用点",没有调度算法本身的改动。
关键实现
/* include/linux/lsm_hook_defs.h */
LSM_HOOK(int, 0, task_setscheduler, struct task_struct *p,
const struct sched_attr *attr__nullable,
const struct cpumask *in_mask__nullable)
/* kernel/sched/syscalls.c -- sched_setaffinity */
retval = security_task_setscheduler(p, NULL, in_mask);
/* kernel/sched/syscalls.c -- __sched_setscheduler (policy/param path) */
retval = security_task_setscheduler(p, attr, NULL);
/* kernel/cgroup/cpuset.c -- cpuset_can_attach / cpuset_can_fork */
ret = security_task_setscheduler(task, NULL, cs->effective_cpus);
security/security.c 里仍由 call_int_hook(task_setscheduler, p, attr, in_mask) 串起所有已注册 LSM;capability / SELinux / Smack 的实现都把两个新参数标 __always_unused,v4 本身不引入新策略,只是把能力递出去。
类比
把 LSM 想象成小区门禁:以前门禁只看到住户的身份证,不知道他要进哪栋楼;现在门禁同时拿到房号,可以拒绝"冒名进顶层"。多租户数据中心里,CPU 隔离核就像"机房冷通道"——调度器是前台分单员,原来只告诉门禁"某某要换工作时段",v4 之后连"工位号"也一并递给门禁。
+-----------+ +----------------------------+ +------------------+
| user task | --> | sys_sched_setaffinity | --> | LSM decision pt. |
| | | security_task_setscheduler | | sees in_mask |
+-----------+ | (p, NULL, in_mask) | +------------------+
+----------------------------+ |
v
+------------------+
| SELinux / Smack |
| BPF / caps |
+------------------+
+-----------+ +-----------------------------+ +------------------+
| user task | --> | sys_sched_setscheduler | -> | LSM decision pt. |
| | | security_task_setscheduler | | sees attr |
+-----------+ | (p, attr, NULL) | +------------------+
+-----------------------------+ |
v
+------------------+
| SELinux / Smack |
| BPF / caps |
+------------------+
Hook signature change (one hook, two new __nullable params):
task_setscheduler(p)
|
v
task_setscheduler(p, attr, in_mask)
| |
NULL when affinity is NULL when policy/param
not changed only, e.g. cpuset attach
Call-site matrix (callers -> what they pass):
sched_setaffinity -> (p, NULL, in_mask)
mipsmt_sched_setaffinity -> (p, NULL, new_mask)
cpuset_can_attach -> (p, NULL, effective_cpus)
cpuset_can_fork -> (p, NULL, effective_cpus)
__sched_setscheduler -> (p, attr, NULL)
timerslack_ns_write -> (p, NULL, NULL)
Highlight:风险与注意点
__nullable是为 BPF verifier 设计的——任何手写 LSM 必须显式判空,否则 verifier 会拒。- SELinux / Smack 当前是机械对齐签名,并没有真实策略;未来要做真实判定时,要决定是基于 task label 还是 cpuset label。
- capability 模块完全忽略两个新参数,仍走
cap_safe_nice()——普通 nice/sched_setscheduler 路径策略不变,只有显式 affinity 请求会被 LSM 拦截。 - v4 之后 Casey 与 Aaron 的 8 月回复在 lore 抓取里被截断,只看到引文前缀,无法判断是否真有质疑点;后续需到 lore 上拉完整邮件。
security:是 patch 主分类前缀,但代码改动入口在kernel/sched/syscalls.c与kernel/cgroup/cpuset.c,归类上是 LSM 基础设施改动,不影响调度器本身的公平性 / 实时性。arch/mips/kernel/mips-mt-fpaff.c是冷门路径,仅在多线程 MIPS 系统编译时需要;交叉编译矩阵要覆盖。
版本变化
- 本 thread 只看到 v4。lore 历史显示存在 v1(2026-05-09)、v2(2026-05-09)、v3(2026-05-26)、v4(2026-07-20)。
- 推测 v3 -> v4 关键变化:把
attr与in_mask都加__nullable;并把mipsmt_sys_sched_setaffinity从只传p改成(p, NULL, new_mask),让 mips FP affinity 路径也透传真实 mask。 - 推测 v1 -> v2 -> v3 主要迭代是"逐步把更多调用点接进来 + 同步 SELinux/Smack 签名"。
一句话总结
v4 给 LSM 的 task_setscheduler 钩子加上 cpumask * 参数,让 SELinux / Smack / BPF LSM 第一次能"看见"并拦截 sched_setaffinity 的目标 CPU,补齐多租户与实时场景下的空间隔离能力。