Skip to content

Optimize & fix numerous detections - #282

Open
MhmRdd wants to merge 6 commits into
bmax121:mainfrom
MhmRdd:fix/sucompat-timing-sidechannel
Open

Optimize & fix numerous detections#282
MhmRdd wants to merge 6 commits into
bmax121:mainfrom
MhmRdd:fix/sucompat-timing-sidechannel

Conversation

@MhmRdd

@MhmRdd MhmRdd commented Jul 22, 2026

Copy link
Copy Markdown

No description provided.

@MhmRdd
MhmRdd force-pushed the fix/sucompat-timing-sidechannel branch from ca04ba8 to 48e90ae Compare July 22, 2026 21:46
MhmRdd added 3 commits July 22, 2026 23:01
get_kstorage walked a per-group linked list, so every su check on the
hot path was O(N) in the number of allowed uids. Replace each group
with a fixed bucket array hashed on did, making lookup, update and
remove O(1) on average.

Traverse with the _rcu iterators to match the _rcu mutators, fix
on_each_kstorage_elem returning 0 through a shadowed rc, and free the
new entry on the memdup_user error path.
The faccessat and newfstatat table hooks add a fixed cost only to
those syscalls, so userspace can detect them by averaging cntvct_el0
timed samples against an unhooked path syscall.

Hook the shared getname_flags path that faccessat, newfstatat, statx,
openat and execve all reach, so every path syscall carries the same
cost. The su path is redirected in place on the already-copied kernel
name, so the callback reads no user memory and faults no page.
The trampoline entry reached the replace address with a RET, but the
entry is a call target, not a return edge, so RET desyncs the return
address stack predictor and mispredicts on every hooked call. Use
branch_absolute so the entry stays a normal branch.
@MhmRdd
MhmRdd force-pushed the fix/sucompat-timing-sidechannel branch from 48e90ae to 8e06e80 Compare July 22, 2026 22:01
@MhmRdd MhmRdd changed the title fix(sucompat): remove faccessat/newfstatat timing side-channel perf: O(1) kstorage lookup, leaner hooks, drop syscall-timing side-channel Jul 22, 2026
@MhmRdd
MhmRdd force-pushed the fix/sucompat-timing-sidechannel branch from 1b4a47f to b322eef Compare July 22, 2026 22:37
The in-place redirect only fired when sh_path fit within the resolved
su path buffer, so a shorter configured su path silently failed to
redirect.

Reallocate through getname_kernel and hand the new filename back via
putname, staying kernel-side so no user stack buffer is written.
getname_kernel and putname are a matched alloc/free pair on every
supported version, so this works across 3.18 - 6.6; log when the su
path still cannot be redirected.
@MhmRdd
MhmRdd force-pushed the fix/sucompat-timing-sidechannel branch from b322eef to 750abdb Compare July 22, 2026 22:38
@MhmRdd MhmRdd changed the title perf: O(1) kstorage lookup, leaner hooks, drop syscall-timing side-channel Optimize & fix numerous detections Jul 22, 2026
MhmRdd added 2 commits July 23, 2026 00:44
before_openat kept copying the openat filename from userspace on every
call even after its one-shot rc redirect was done, and before_execve
copied the exec filename for every caller. Both let an unprivileged app
detect the hook by timing and by the page it faults in.

Return before the compat_strncpy_from_user: in before_openat once the
redirect has run, and in before_execve for callers that are neither
root nor the trusted manager. The locals are still zeroed and the auto
su flag is still set first, so the after handlers and every boot-time
trigger are unchanged.
before_openat only self-unhooks after a rc file matches. If no match
ever happens the hook stays live into app runtime, where the replaced
early-return is not taken and every openat is copied from userspace,
letting an app detect it by timing and residency.

Return for non-root callers. The rc files are opened by init as root,
so the redirect still fires, while app openat calls no longer reach the
user read.
@MhmRdd
MhmRdd force-pushed the fix/sucompat-timing-sidechannel branch from 78882fa to cd52cf0 Compare July 22, 2026 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants