Skip to content

L04: inode_setattr LSM hook produces no events on chmod(2) #21

Description

@espadonne

Symptom

`chmod-undo-linux.sh` smoke times out after 10s waiting for `discriminant = 'FilePreImage'` (or any event) on a `chmod 0755 foo.txt` operation. Journal dump after the chmod is empty.

Reproduction

Run `chmod-undo-linux.sh` against the self-hosted runner (or any host where `pick_linux_tier` selects `ebpf-lsm`).

Confirmed on the linux-kernel-capture (L02/L03/L04) matrix job, run 26253871697 rerun — rest of the matrix passes after the helper-side startup race fix (PR #20).

What we know

  • Helper log shows `ebpf-lsm inode_setattr loaded and attached hook="inode_setattr" prog="shit_inode_setattr" ringbuf="setattr_events"` well before the chmod runs.
  • Tier picked is `ebpf-lsm (L04)` (`SHIT_FORCE_TIER=ebpf-lsm`).
  • BPF feature detection reports BTF + bpf_perf_link + bpf_cookie all available.
  • Other LSM hooks attached on the same boot DO produce events: `file_open` (edit-undo smoke ✓), `inode_unlink` (rm-undo ✓), `inode_mkdir` (mkdir-undo ✓), `inode_rename` (mv-undo ✓).
  • Only `inode_setattr` is silent.

Contract from the smoke

The chmod smoke explicitly expects `inode_setattr → FilePreImage` (`tests/smoke/chmod-undo-linux.sh:92-94`):
```

eBPF-LSM setattr emits the same FilePreImage event wire as fanotify-perm

does for open-then-write. The daemon's metadata-restore path reads the

old mode/uid/gid from the FilePreImage record on undo.

smoke_wait_for_event "discriminant = 'FilePreImage'" 1 10
```

So the protocol intent is: chmod fires inode_setattr → BPF writes to setattr_events ringbuf → helper translates to a FilePreImage event carrying old mode/uid/gid → daemon journals it.

Three places the bug could live

  1. BPF program does not fire on chmod(2) — the LSM hook may need an explicit `fmod_ret` / `fexit` signature, or it's attached but the kernel doesn't trigger it for chmod (e.g., chmod goes through `inode_setattr` only when `mode` changes; ATTR_MODE in the iattr).
  2. BPF program fires but doesn't write to setattr_events — early return on filter (pid exclusion, watch-tree empty), or ringbuf reserve/submit bug.
  3. Helper reads setattr_events but doesn't translate to FilePreImage — the userspace consumer in shit-helper/src/ebpf/ may emit a different discriminant (MetadataChange) or drop the event.

Next steps for investigation

  • Add a `bpf_printk` (or `trace_printk`) at the top of `shit_inode_setattr` and run a chmod under the helper; check `/sys/kernel/debug/tracing/trace_pipe`. If silent: case (1). If chatty: case (2) or (3).
  • Audit the helper's ringbuf reader for `setattr_events` (probably in `crates/shit-helper/src/ebpf/reader.rs` or similar) — verify it constructs a `FilePreImage` capture event with the captured mode/uid/gid, not a `MetadataChange`.
  • Cross-check the iattr.ia_valid flag handling in the BPF program — chmod sets ATTR_MODE only, while `chown` sets ATTR_UID/ATTR_GID, and `touch` sets ATTR_ATIME/ATTR_MTIME. The program may be filtering for the wrong flags.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions