Skip to content

Fix reading Unix addresses whose path fills all of sun_path - #1742

Open
EnesKartal wants to merge 1 commit into
bytecodealliance:mainfrom
EnesKartal:unix-108-byte-path
Open

EnesKartal wants to merge 1 commit into
bytecodealliance:mainfrom
EnesKartal:unix-108-byte-path

Conversation

@EnesKartal

Copy link
Copy Markdown

Fixes #1741.

On Linux, when a Unix socket is bound to a path that fills all 108 bytes of sun_path, the kernel stores the NUL terminator just past sun_path (inside the sockaddr_storage) and returns an address length of 111. read_sockaddr_unix then indexed sun_path[108] to check the terminator and panicked, in both backends:

  • linux_raw: src/backend/linux_raw/net/read_sockaddr.rs:124
  • libc: src/backend/libc/net/read_sockaddr.rs:220

This happens in SocketAddrUnix::try_from(SocketAddrAny) and in Debug for SocketAddrAny, for addresses returned by getsockname, recvfrom, accept and similar.

The fix checks the terminator only when it lies inside sun_path. A full-length path is passed to SocketAddrUnix::new, which already supports the non-terminated 108-byte form (see test_long_named_address).

Test plan

New test test_getsockname_long_named_address in tests/net/unix.rs binds a datagram socket to a 108-byte path in a temp dir, formats the getsockname result with Debug, converts it to SocketAddrUnix and checks path_bytes().

Before the fix:

$ cargo test --features net,fs --test net test_getsockname_long_named_address
thread 'unix::test_getsockname_long_named_address' panicked at src/backend/linux_raw/net/read_sockaddr.rs:124:20:
test result: FAILED. 0 passed; 1 failed
$ cargo test --features net,fs,use-libc --test net test_getsockname_long_named_address
thread 'unix::test_getsockname_long_named_address' panicked at src/backend/libc/net/read_sockaddr.rs:220:16:
test result: FAILED. 0 passed; 1 failed

After the fix (Linux x86_64):

$ cargo test --features net,fs --test net
test result: ok. 74 passed; 0 failed
$ cargo test --features net,fs,use-libc --test net
test result: ok. 74 passed; 0 failed

cargo fmt is clean and cargo clippy --tests shows no warnings in the changed files for either backend.

On Linux, a socket bound to a 108-byte path reports an address length
that includes the NUL terminator, which the kernel stores just past
sun_path. Converting such an address to SocketAddrUnix, or formatting a
SocketAddrAny holding it, indexed sun_path out of bounds and panicked in
both backends. Only check for the terminator when it is inside sun_path.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A 108-byte Unix peer pathname still panics address conversion after the earlier termination fix

1 participant