Skip to content

fix(ingestor): stats .tmp writer follows a hard link to another file of the ingestor's user #228

Description

@dborup

Relates to #160, #161, #216

Problem

A hard link at <stats path>.tmp that points to another file owned by the ingestor's user passes the regular-file and owner checks in writeStatsAtomic. The writer then truncates that file, overwrites it with the stats JSON, and the rename publishes it.

Proposed fix

  • After the open, refuse a tmp whose Fstat shows nlink > 1, and leave it in place.
  • Report it with the same statsWriteError shape, e.g. <tmp>: hard-linked (nlink N); remove it.

Acceptance

  • A Unix test with a hard link at the tmp path gets an error, the link target stays unchanged, and nothing is published.
  • The existing stats-file tests stay green.

Activity

  1. dborup commented on Oct 4, 2026

    @dborup
    OwnerAuthor

    Additional items for the same code, from the round-2 re-review of #216 (merged). Please handle them together with the hard-link fix:

    1. FIFO tests without a release guard.
      • The FIFO subtest of TestStatsWriteErrorNamesThePathOnce_160 calls writeStatsAtomic directly.
      • TestStatsFileWriterFailureLineNamesThePathOnce_160 calls stop() unguarded.
      • If fix(ingestor): a FIFO at the stats .tmp path blocks the stats writer forever #161 regressed (e.g. O_NONBLOCK dropped), both would hang until the package timeout instead of failing in seconds.
      • Route them through writeStatsAtomicOrRelease and a guarded stop.
    2. The rename failure path is untested. A mutant that stops stripping the *os.LinkError survives. Add a rename-failure case to TestStatsWriteErrorNamesThePathOnce_160, such as a non-empty directory at the destination.
    3. DRY. The owner detail and hint (owned by uid %d, ingestor uid %d / remove it or fix its owner) are built in both setPermissionHint and checkStatsTmpOwner. Extract one helper.
  2. added a commit that references this issue on Oct 5, 2026
  3. dborup commented on Oct 5, 2026

    @dborup
    OwnerAuthor

    Fixed by #240 (merged as e0bfe955).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions