Skip to content

FD gap: virtual FDs in [1024, 32768) are untracked #8

@jserv

Description

@jserv

Rationale

The FD table uses two ranges: low_fds[1024] for FDs 0..1023 (populated only via dup2/dup3) and entries[4096] for FDs 32768+ (auto-allocated). fd_lookup() returns NULL for FDs in [1024, 32768), so dup2/dup3 targeting this range fails with EBADF.

Normal auto-allocation never enters the gap -- only explicit FD placement is affected (e.g., exec 1025>/dev/null).

Proposed Changes

Option A: Extend low_fds[] to cover [0, 32768), eliminating the gap entirely. ~1MB overhead per instance (32 bytes × 31K entries). Simple, no algorithmic changes.

Option B: Sparse hash map for gap range, keep existing arrays for hot paths. Zero overhead when gap FDs are unused, added code complexity and potential cache misses on lookup.

Option C: Log/debug-trace when dup2 targets the gap and document the limitation. Externally still EBADF -- dup2 semantics cannot surface a differentiated errno.

Considerations

  • Most real-world programs never dup2 into [1024, 32768); the gap primarily affects edge cases
  • Must preserve KBOX_FD_BASE=32768 auto-allocation strategy since seccomp ADDFD injection depends on it
  • Unit tests in tests/unit/ cover fd_lookup, insert_at, and removal; new tests needed for gap-range FDs
  • Option A is simplest but adds ~1MB per kbox instance
  • Option B preserves memory efficiency but adds complexity to a hot path

References

  • src/fd-table.h : constants and data structure definition
  • src/fd-table.c : fd_lookup() returns NULL for gap range; insert_at() fails when lookup returns NULL
  • src/seccomp-dispatch.c : forward_dup2() returns EBADF on insert failure

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions