Unix getsockname succeeds without writing its address

perfloop-oss/cpp2rust · UNCATALOGUED CORRECTNESS

https://perfloop.ai/t/oss/case_kpsk46099k

Verdict

VERIFIED · settled 2026-11-03 · merged as Cpp2Rust/cpp2rust#584

What happened: The assertion is violated on the comparison and satisfied with this change.

Hypothesis

Refcount getsockname can leave a Unix socket's output address unchanged while reporting success. Even an unnamed socket loses the family bytes a caller needs to interpret the result. Application exposure remains unmeasured.

The refcount socket creation rule explicitly accepts AF_UNIX, and the C getsockname rule imposes no IP-only restriction. After a successful query, f12 always calls Sockaddr::encode and then returns zero. encode handles only Inet and Inet6; Unix reaches its no-op fallback before out_len is written. This is missing writeback for an existing supported family, not a request to expand the family API.

checkProperty(prop_gpcdy1avqq) at e2b679de9fa36c3b015b4604759ab0ff53003fa4 ran cargo test --manifest-path libcc2rs/Cargo.toml --test perfloop_sockaddr_families -- --nocapture --test-threads=1. Eight unbound IPv4/IPv6 full-size byte controls passed. Observation nine used an unbound Unix datagram socket, capacity two, two physical bytes and fill zero. Native libc succeeded and wrote [1,0]. encode completed without panic and left [0,0]. Both returned lengths were two. The six-byte replay is stored on the node; the planned twelve-observation grid did not finish. An earlier fixture attempt stopped at an unavailable IPv6 loopback bind and supplied no Unix semantic evidence. The retained witness uses no bind or interface address.

The smallest Case check is the saved public-runtime replay, followed by a native-C/refcount fixture on an unnamed Unix socket and a pathname-bound Unix socket. Matching family and valid name bytes, normal status, actual length and a protected suffix would confirm the contribution. An unchanged baseline that already writes those supported outputs would reject it. Pathname output and end-to-end translation have not yet been tested. A Unix branch can be added independently of the IP caller-limit and returned-length fixes; no performance gain is claimed.

The latest upstream refresh still shows https://github.com/Cpp2Rust/cpp2rust/pull/579 and https://github.com/Cpp2Rust/cpp2rust/pull/561. Their inspected implementations change standard descriptors/streams and empty-initializer rule matching, not Unix address writeback. Prior searches for Sockaddr, getsockname and socket writeback found no covering repair.

Change to test: Write the family and address bytes for the already-supported Unix socket forms instead of treating them as a successful no-op. Reuse bounded writeback and actual-length handling without adding support for unrelated address families.

Where it lives

perfloop-oss/cpp2rust · rules/socket/tgt_refcount.rs

Evidence

The assertion is violated on the comparison and satisfied with this change: `On Linux, refcount getsockname for unnamed Unix sockets and pathname-bound Unix sockets with 1 through 107 byte names matches native libc status, address bytes and actual length for every capacity from zero through the address length plus one, preserving the output suffix, for stream and datagram sockets.`

Checks: 6 of 6 passed. Verification: no defect found.

Timeline