[RFC PATCH 0/2] apparmor: mediate asynchronous file signals
From: Shi Lecun
Date: Sat Nov 07 2026 - 12:01:12 EST
This series extends AppArmor's signal send/receive mediation to
file-generated SIGIO and SIGURG notifications and fixes a separate
missing permission check in the SIGIO fallback path. It is based on
v7.4-rc1.
On the unmodified kernel, a direct kill() to a task in an enforcing
profile that denies SIGIO reception fails with EACCES, but the task can
still receive an asynchronous pipe notification.
File-generated signals use file_send_sigiotask rather than task_kill,
and AppArmor does not implement file_send_sigiotask. The same gap
affects sender-side rules and SIGURG. Should AppArmor's signal
send/receive rules cover this path, or are file-generated notifications
intentionally outside its signal mediation model?
Patch 1 records the credentials of the task that sets the file owner
and uses them as the sender identity at delivery. It resolves the
newest sender and recipient labels and checks both send and receive
permissions. The existing fown lock protects the saved credentials;
the task triggering I/O is not treated as the signal sender.
Under this model, policy replacement is followed through newest-label
lookup, but a later change_profile by the owner setter does not change
the sender label until ownership is set again. Is retaining the setter's
credentials for the lifetime of the owner registration the intended
sender model? If not, should an existing registration instead follow
the setter's profile changes? This is the main question I would like to
settle before posting a non-RFC version.
Patch 2 fixes a separate issue exposed by this mediation: if queuing
the signal configured with F_SETSIG fails, fcntl falls back to SIGIO
without checking permission for SIGIO. The patch adds the fallback
check only when the configured signal differs from SIGIO. It is not
AppArmor-specific, although runtime testing used AppArmor with patch 1.
Is rechecking permission for SIGIO immediately before fallback the
appropriate generic behavior, independent of the LSM enforcing the
policy?
I found this issue using kemcat, a tool I am developing as part of my
research. kemcat is a harness that checks whether every security-relevant
effect is actually mediated by LSM hooks, combining static
hook/implementation census, ftrace shadow observation, and generated
effect-class inputs judged by an independent effect oracle.
The 19-case reproducer checks the proposed mediated behavior and
produced these results on x86-64 QEMU/KVM with AppArmor 4.1.8,
UID/GID 1000 tasks, PROVE_LOCKING and DEBUG_ATOMIC_SLEEP:
v7.4-rc1: 7/19 passed
with patch 1: 18/19 passed (SIGIO fallback)
with both patches: 19/19 passed
Tests cover send/receive denials, allowed signals, F_SETSIG,
process-group and TID owners, profile transitions, owner replacement,
unconfined senders, TCP urgent notifications and queued-signal fallback.
Builds produced no compiler warnings, and the final guest log contained
no lockdep or atomic-sleep warnings. The reproducer and complete logs
are available on request.
I have not run the full AppArmor regression suite or separately tested
policy reload, stacked profiles, concurrent owner updates, or hardware
hard-IRQ delivery. Patch 2 has not been runtime-tested with SELinux or
Smack policies.
This series was developed with LLM assistance.
Shi Lecun (2):
apparmor: mediate file-generated signals
fcntl: recheck signal permissions before falling back to SIGIO
fs/fcntl.c | 3 +++
security/apparmor/include/file.h | 2 ++
security/apparmor/lsm.c | 41 +++++++++++++++++++++++++++++++-
3 files changed, 45 insertions(+), 1 deletion(-)
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
--
2.56.0