Skip to content

NAS-143100 / 26.0.0-RC.1 / audit: do not follow a stale filename->aname back-pointer (by ixhamza) - #352

Merged
creatorcary merged 1 commit into
release/26.0.0-RC.1from
NAS-143100-26.0.0-RC.1
Sep 4, 2026
Merged

NAS-143100 / 26.0.0-RC.1 / audit: do not follow a stale filename->aname back-pointer (by ixhamza)#352
creatorcary merged 1 commit into
release/26.0.0-RC.1from
NAS-143100-26.0.0-RC.1

Conversation

@bugclerk

@bugclerk bugclerk commented Sep 4, 2026

Copy link
Copy Markdown

Fixes the panics seen on 6.18 during truenas_s3 testing. They all trace to one bug, a use-after-free in __audit_inode() reached from io_uring path operations, analysed by @anodos325 from the pstore dumps. Reproducible on both our 6.18 and 6.12 trees, but scoped to 6.18 here since 6.12 has no io_uring callers that pass pathnames, Samba's vfs_io_uring only submits fd-based data ops which take no struct filename. One thing to call out, clearing ->aname alone isn't enough. It covers the task-work path but not io-wq, where the worker can load the pointer before the submitter clears it and dereference it after, so the patch also validates the pointer in __audit_inode() before using it. One behaviour change too, io_uring_enter(2) no longer logs its own PATH record for these ops. That was the broken one anyway, it reported an inode io_uring_enter(2) never looked up. The op is still audited on the URINGOP event and audit used to log name=(null) for these, now it logs the real path.

This is a targeted fix rather than mainline's approach, and that's the reason for keeping it downstream only. Mainline fixed it in io_uring instead, so it never hands audit a filename from another context. Ours just stops audit following the stale pointer. I did try backporting mainline's, but it's one commit out of a series that rewrites getname_flags(), 266 lines across 6 files including linux/fs.h. Since we update our kernel trees actively, that would drift us from LTS. Stable can't take mainline's either, it caps patches at 100 lines, and the series has no Fixes: tag or Cc: stable so the tooling never saw it. 27 moves to a 7.x kernel which already has the proper fix, so this carry has a natural end.

Testing

Ran under KASAN with audit rules loaded, driving the affected opcodes over both the io-wq and task-work paths. 6.18.48 goes from 4879 reports to 0, and 0 with no rules loaded. Ordinary syscall audit records are unchanged, and an inode-keyed rule still matches the io_uring operations, checked against stock and patched kernels.

Original PR: #351

…me->aname

__audit_getname() caches a back-pointer to the audit_names record in
filename->aname and __audit_inode() follows it.  Nothing invalidates it.
io_uring calls getname() in ->prep() but issues the operation later, on
an io-wq worker or from task work, so the submitting syscall exits and
audit_free_names() frees the record while io_uring still holds the
filename.  __audit_inode() then writes into freed memory:

  BUG: KASAN: slab-use-after-free in __audit_inode+0x45e/0xa10
  Read of size 8 by task iou-wrk-422/433

Look the record up by identity among the records the current context
owns instead.  Every record on names_list holds a reference on its
filename, so a match cannot name a freed one.  Clearing the back-pointer
in audit_free_names() would not be enough on its own: the freeing and
reading contexts are different tasks, so the store races the read, and
audit_free_names() hands the same preallocated_names[] slot back out at
the same address, so validating the pointer by address accepts a
recycled record.

Mainline fixed this differently, in commit 9fa3ec84587c ("allow
incomplete imports of filenames"), part of a series that reworks
getname_flags() and does not apply to this tree.

Signed-off-by: Ameer Hamza <ameer.hamza@truenas.com>
(cherry picked from commit c6e5cc0)
@bugclerk

bugclerk commented Sep 4, 2026

Copy link
Copy Markdown
Author

@ixhamza

ixhamza commented Sep 4, 2026

Copy link
Copy Markdown
Member

time 14:00

@creatorcary
creatorcary merged commit e3e4f02 into release/26.0.0-RC.1 Sep 4, 2026
8 checks passed
@creatorcary
creatorcary deleted the NAS-143100-26.0.0-RC.1 branch September 4, 2026 18:23
@bugclerk

bugclerk commented Sep 4, 2026

Copy link
Copy Markdown
Author

This PR has been merged and conversations have been locked.
If you would like to discuss more about this issue please use our forums or raise a Jira ticket.

@truenas truenas locked as resolved and limited conversation to collaborators Sep 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants