[PATCH v2 0/3] security, sched: Expand task_setscheduler LSM hook and related fixes

Aaron Tomlin atomlin at atomlin.com
Sat May 9 21:38:00 UTC 2026


Hi,

This series expands the task_setscheduler LSM hook to include the requested
CPU affinity mask, enabling BPF-based security modules to enforce strict
spatial isolation boundaries. During the development of this expansion, two
pre-existing subsystem bugs were identified and fixed.

In modern multi-tenant and real-time environments, CPU isolation is a
critical boundary. Currently, the task_setscheduler hook lacks visibility
into the actual CPU affinity mask being requested via sched_setaffinity()
or cgroup migrations. This limits the effectiveness of eBPF-driven security
policies when attempting to monitor and shield specific cores.

By expanding the LSM hook signature, BPF LSMs are provided with the
necessary context to audit and even restrict specific CPU pinning requests.

    Patch 1 (cgroup/cpuset): Fixes a pre-existing deadline (DL) bandwidth
    metric leak in cpuset_can_attach(). It was discovered that if a task
    fails its security checks mid-batch during a thread group migration,
    the loop aborts without unwinding previously accumulated DL metrics
    (nr_migrate_dl_tasks and sum_migrate_dl_bw). This patch introduces an
    out_unlock_reset path to guarantee clean unwinding.

    Patch 2 (security): Implements the core LSM hook expansion. It safely
    propagates either the requested cpumask (via sched_setaffinity and
    cpuset_can_attach) or passes NULL for unchanged affinities. It also
    adds proper __nullable annotations to ensure the BPF verifier mandates
    explicit NULL checks for attached eBPF programs, and mechanically
    updates SELinux, Smack, and Commoncap.

    Patch 3 (mips): Resolves a critical memory corruption vulnerability in
    the MIPS MT architecture's sched_setaffinity implementation. When
    CONFIG_CPUMASK_OFFSTACK=y is enabled, copy_from_user() was clobbering
    the stack pointer due to an invalid sizeof() evaluation, followed by an
    uninitialised heap allocation. This patch safely reorders the
    allocations and properly utilises cpumask_size().

These patches have been logically separated to assist subsystem maintainers
with review and backporting.

Comments and feedback are welcome.

Kind regards,


Changes since v1 [1]:
 - Reordered the allocation and user-copy of new_mask in the MIPS
   architecture's mipsmt_sys_sched_setaffinity() to occur before the
   LSM hook is invoked. This ensures the security modules evaluate a fully
   populated mask rather than uninitialised memory, while cleanly handling
   error unwinding

 - Updated cpuset_can_fork() to pass the destination cpuset's effective CPU
   mask instead of NULL

[1]: https://lore.kernel.org/lkml/20260509164847.939294-1-atomlin@atomlin.com/


Aaron Tomlin (3):
  cgroup/cpuset: Fix deadline bandwidth leak in cpuset_can_attach()
  security: Expand task_setscheduler LSM hook to include CPU affinity
    mask
  mips: sched: Fix CPUMASK_OFFSTACK memory corruption

 arch/mips/kernel/mips-mt-fpaff.c | 46 +++++++++++++++++---------------
 fs/proc/base.c                   |  2 +-
 include/linux/lsm_hook_defs.h    |  3 ++-
 include/linux/security.h         | 11 +++++---
 kernel/cgroup/cpuset.c           | 13 ++++++---
 kernel/sched/syscalls.c          |  4 +--
 security/commoncap.c             |  7 +++--
 security/security.c              | 11 ++++----
 security/selinux/hooks.c         |  3 ++-
 security/smack/smack_lsm.c       | 11 ++++++--
 10 files changed, 67 insertions(+), 44 deletions(-)

-- 
2.51.0




More information about the Linux-security-module-archive mailing list