Skip to content

About

Linux fanotify FID (File Identifier) mode event parser and file handle utilities.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

116 Commits

Folders and files

Repository files navigation

fanotify-fid

A Rust library for Linux fanotify: it parses what the kernel reports, resolves file handles to paths, and writes permission decisions.

Crates.io Docs.rs License: MIT

Overview

fanotify watches operations on objects, reports the process, and in its permission classes holds the operation inside the kernel until you answer.

What it hands you is a byte stream, in one of three identities: an open descriptor per event, a file handle plus fsid (FID), or a mount id. The FID form is the one that scales to a whole filesystem, because the kernel holds no descriptor per watched object — and it is variable-length records behind a fixed header, so a fixed-stride reader parses garbage. This crate reads all three, byte for byte.

Features

  • All three identities, all nine info record types, and the fields 0.7.x used to drop: both sides of a FAN_RENAME, the mount id, the access range, filesystem errors, and the pidfd.
  • FidEvent<'buf> borrows the buffer it was parsed from, so a parse copies no record's bytes. EventReader owns the buffer and the event storage: one allocation for the first batch, none after it.
  • PathResolver turns handles into paths, reading the store through a borrow and teaching it through a separate PathMemo — so a hit copies nothing, a store behind a lock can answer, and a batch of events about one directory costs one open_by_handle_at instead of one per event. Plug in your own cache, or none.
  • Reading, resolving and learning are three calls with three signatures, and each one says what it costs: EventReader::read borrows, resolve_events only reads, resolve_events_memo learns, and Fanotify::read_events is the owned form for a batch that has to move to another thread.
  • Permission answers in all their forms, including the audit record and any record type a newer kernel adds — built without a heap buffer.
  • Every errno is the kernel's. Nothing is pre-validated, so a refusal is the kernel's own and says which syscall refused it.
  • No hidden state: no table of marked paths, no eviction policy, no silent re-scan. Marks live in the kernel; caches are yours.

Install

[dependencies]
fanotify-fid = "0.9"

Rust 1.88 or newer, one dependency (libc). A FID group needs no privilege; resolving its handles needs CAP_DAC_READ_SEARCH.

cargo run --example batch_to_worker
cargo test
sudo -E cargo test -- --ignored --test-threads=1

Testing

The suite runs against a real kernel, not a mock. tests/baseline.rs asserts every legal group configuration and every combination that must not exist, and reads the capability actually held, because the privilege check runs before the legality check. tests/allocation.rs counts allocations to hold the API to its zero-copy claims. tests/properties.rs asserts the invariants no example can show. fuzz/ has three targets for malformed input. The 32 unsafe blocks are syscall calls, unaligned reads of the kernel's records, and two OwnedFd constructions, each with a SAFETY comment.

Documentation

SPEC.md — the behavioural contract, the five legal group configurations, the privilege and kernel-version tables, and the test gates.

rustdoc — the API, and the authority whenever anything disagrees with prose.

examples/ — batch_to_worker reads a batch, copies it once and parses it on a worker thread; prelude_usage is the shortest path in; resolve_after_rename shows which cached entries a rename invalidates.

License

MIT

About

Linux fanotify FID (File Identifier) mode event parser and file handle utilities.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages