Positive Backlog can be truncated in listen(2) on 64-bit platforms
low swesweep-fasthttp · tcplisten/tcplisten.go · (*Config).fdSetup · run #4
Description
A positive cfg.Backlog larger than the platform C int range is passed directly to unix.Listen. On 64-bit targets the syscall can truncate the value, allowing an attacker-controlled Backlog (for example 1<<32) to bypass the backlog <= 0 default check and effectively set a zero or invalid backlog, degrading or failing the listener.
Triage
Not triaged.
Raw scan report for this file
I analyzed the file against the public API threat model: `(*Config).NewListener(network, addr)` is the trust boundary, with caller-controlled `network`, `addr`, and `Config` fields such as `ReusePort`, `DeferAccept`, `FastOpen`, and `Backlog`.
Key flows:
- `addr` and `network` go into `net.ResolveTCPAddr`. The error is checked.
- The resolved IP is copied into fixed-size `unix.SockaddrInet4.Addr` or `unix.SockaddrInet6.Addr` via `copy(dst, src)`. `copy` bounds-checks the destination, and `To4()`/`To16()` either return the correct-sized slice or nil. A nil source only leaves the address zero-filled; it does not overflow the fixed buffers.
- Zone handling calls `net.InterfaceByName`, checks the error, and converts the interface index with `safeIntToUint32`, which rejects negative values and values above `MaxUint32`.
- `fdSetup` configures socket options, binds, and listens. Negative or zero `Backlog` falls back to `soMaxConn()`. Positive `Backlog` is passed to `unix.Listen` without clamping to the platform C `int` range.
- `NewListener` creates the fd, calls `fdSetup`, safely converts fd to `uintptr`, wraps it with `os.NewFile`, converts it with `net.FileListener`, and closes the temporary file/listener on error.
Most of the address-parsing and integer-conversion logic is safe. The notable reachable issues are:
1. A nil `*Config` receiver can cause a panic in `fdSetup` after a socket fd has already been allocated.
2. A positive `Backlog` larger than the platform C `int` range can be truncated in the `listen(2)` syscall on 64-bit systems, allowing an attacker-controlled config value to effectively set an invalid or zero backlog.
Other observations, such as ignored best-effort `Close()` errors in error paths, DNS side effects from caller-supplied hostnames, and platform-dependent dual-stack behavior, are lower-signal robustness concerns rather than clear zero-day vulnerabilities.
```json
[
{
"severity": "medium",
"title": "Nil Config receiver can panic in NewListener",
"function": "(*Config).NewListener",
"description": "NewListener can be invoked with a nil *Config receiver. It calls cfg.fdSetup without checking cfg, and fdSetup dereferences cfg.ReusePort. This causes a nil pointer dereference after the socket fd has been allocated; an unrecovered panic crashes the host process, and a recovered panic can leak the fd."
},
{
"severity": "low",
"title": "Positive Backlog can be truncated in listen(2) on 64-bit platforms",
"function": "(*Config).fdSetup",
"description": "A positive cfg.Backlog larger than the platform C int range is passed directly to unix.Listen. On 64-bit targets the syscall can truncate the value, allowing an attacker-controlled Backlog (for example 1<<32) to bypass the backlog <= 0 default check and effectively set a zero or invalid backlog, degrading or failing the listener."
}
]
```