Subject
nix 0.29.0 is a set of Rust wrappers over the Unix/POSIX system-call API exposed by the libc crate. It covers sockets, signals, process control (fork, exec, wait, clone), memory mapping, file and directory operations, terminal control, scheduling, ptrace, and dozens of smaller POSIX surfaces. The public API mirrors C headers module-by-module (sys::socket, sys::signal, unistd, sys::mman, and so on) and translates C error returns into a Result<T, Errno>. Every capability beyond a small core is feature-gated, and platform differences are handled by extensive cfg gating across Linux, the BSDs, the Apple targets, the Solaris-like systems, and others. It is one of the most widely depended-on crates in the Rust ecosystem for direct syscall access.
Methodology
Tooling: openvet 0.6.0, ripgrep, diff, git, wc. I read Cargo.toml, Cargo.toml.orig, and build.rs in full, then surveyed the source with ripgrep to map where unsafe, extern "C", FFI, and the various I/O surfaces live. The crate is roughly 32.5K lines across 62 files with about 825 occurrences of unsafe, a very high density driven by one focused libc FFI call per wrapper. Rather than read all 825 sites, I read the representative high-risk paths end-to-end: the NixPath/with_nix_path CStr conversion in lib.rs, the cmsg decode and sockaddr from_raw machinery in sys/socket, the recvmsg/sendmsg msghdr packing, errno sentinel handling, the SigAction handler transmutes in sys/signal, fork/exec/pipe/getgroups in unistd, the mmap family in sys/mman, the WaitStatus/siginfo decode in sys/wait, the clone callback in sched, and clearenv in env. I diffed contents against vcs.
Results
Every file under contents/src is byte-identical to the VCS checkout; only Cargo.toml differs, from cargo's publish-time normalisation. The VCS tree is a full git repository.
The crate is built almost entirely on unsafe FFI, so uses-unsafe holds. The unsafe is minimal in the sense that each block is a single libc call or the pointer/length setup feeding one (unsafe-minimal), and it is documented through // SAFETY:/Safe because comments and # Safety doc sections, with the crate compiled under #![deny(unsafe_op_in_unsafe_fn)] (unsafe-documented). Across the reviewed paths the FFI preconditions hold (unsafe-safe): with_nix_path bounds its stack buffer and rejects interior NULs (lib.rs:287-330); cmsg decoding reads every payload with ptr::read_unaligned and bounds-checks the SO_EE_OFFENDER address (sys/socket/mod.rs:855-1016); sockaddr from_raw validates length against the target struct size before copying and re-checks family and length in its accessors (sys/socket/addr.rs:1132-1232); the mmap family checks MAP_FAILED before building a NonNull (sys/mman.rs:395-449); and Errno::result applies the standard -1/MAP_FAILED/SIG_ERR sentinel-to-errno translation.
The socket wrappers issue raw network syscalls and validate the sockaddr length and family before exposing typed views, justifying uses-network and network-safe; nix sits below the protocol layer and has no TLS-by-default notion, so network-secure was not asserted. The exec* family launches process images in argv form from caller-supplied CStr values with a NULL-terminated array built by to_exec_array (uses-exec, exec-safe), and fork/clone are unsafe fns whose async-signal-safety and stack-overflow contracts are documented (unistd.rs:808-855), supporting uses-concurrency, concurrency-safe, and concurrency-documented. nix wraps libc's threading and process primitives rather than implementing its own, so impl-concurrency is false. Path-taking wrappers forward caller paths straight to libc without adding traversal logic (uses-filesystem, filesystem-safe), and clearenv only clears the environment on request, documenting its thread-safety precondition and never enumerating or transmitting the environment (env.rs:41-63), supporting uses-environment and environment-safe.
build.rs only invokes cfg_aliases! and emits cargo:rustc-check-cfg lines; it reads no files, makes no network calls, and spawns nothing (has-build-exec, build-exec-safe, build-exec-deterministic, build-exec-no-network, build-exec-no-write-out, build-exec-minimal). The crate ships no precompiled artifacts and no install hook (has-binaries, has-install-exec). It contains unit tests in src (chiefly sockaddr round-trip and size checks in addr.rs) and a substantial integration suite under test/ (has-unit-tests, has-integration-tests), but no fuzz or property-test harness in the published crate (has-fuzz-tests, has-property-tests); for that reason unsafe-tested was not asserted. nix performs no cryptography (the only crypto-named symbols are kernel-TLS socket-option enums), runs no interpreter or JIT, and implements no parser, protocol, data structure, or general algorithm of its own, so uses-crypto, uses-jit, uses-interpreter, impl-crypto, impl-parser, impl-interpreter, impl-jit, impl-protocol, impl-datastructure, and impl-algorithm are all false. A scan for obfuscation, encoded blobs, suspicious endpoints, and telemetry found only legitimate documentation URLs, supporting is-benign. No findings were recorded.
Conclusion
nix 0.29.0 is a thin, heavily cfg-gated FFI layer with about 825 unsafe sites, each a focused libc call. The reviewed high-risk paths, cmsg decode, sockaddr length handling, msghdr packing, the mmap family, fork/exec, signal-handler transmutes, and the CStr boundary, uphold their libc preconditions: unaligned reads where alignment is not guaranteed, length-and-family validation before copying kernel data, MAP_FAILED checks before NonNull construction, and consistent sentinel-to-errno translation. Functions whose safety cannot be enforced at the type level (fork, clone, sigaction, clearenv) are unsafe fns with documented contracts. Source is byte-identical to VCS, the build script is inert, and no malicious or obfuscated code was found. The audit recorded no findings. The unsafe review was representative rather than exhaustive across all 825 sites, and the published crate carries no fuzz or property-test harness.