Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix using SockaddrStorage to store Unix domain addresses on Linux #1871

Merged
merged 1 commit into from Nov 21, 2022

Conversation

asomers
Copy link
Member

@asomers asomers commented Nov 19, 2022

Since it has variable length, the user of a sockaddr_un must keep track of its true length. On the BSDs, this is handled by the builtin sun_len field. But on Linux-like operating systems it isn't. Fix this bug by explicitly tracking it for SockaddrStorage just like we already do for UnixAddr.

Fixes #1866

Since it has variable length, the user of a sockaddr_un must keep track
of its true length.  On the BSDs, this is handled by the builtin sun_len
field.  But on Linux-like operating systems it isn't.  Fix this bug by
explicitly tracking it for SockaddrStorage just like we already do for
UnixAddr.

Fixes nix-rust#1866
@asomers asomers force-pushed the sockaddr_storage_unix_addr_linux branch from 63403e7 to fa62534 Compare November 19, 2022 20:54
@asomers
Copy link
Member Author

asomers commented Nov 19, 2022

@stevenengler could you test your code with this PR please?

Comment on lines +1546 to +1550
if i32::from(ss.ss_family) == libc::AF_UNIX {
// Safe because we UnixAddr is strictly smaller than
// SockaddrStorage, and we just initialized the structure.
(*(&mut ss as *mut libc::sockaddr_storage as *mut UnixAddr)).sun_len = len as u8;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A libc::sockaddr_storage was initialized above, but I don't think that means that those bytes represent a valid UnixAddr? For example libc::sockaddr_storage has 6 padding bytes on Linux x86-64 that may not be zeroed, and reading those uninitialized bytes as a UnixAddr would be UB. I think this would only occur if len is less than 8 (sizeof(u16) + 6). Edit: And only if the UnixAddr were to read bytes past len. But as long as internally UnixAddr makes sure to never read past len - offsetof(sun_path) bytes of sun_path, then I think it would be fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs for mem::zeroed say that padding bytes may not be initialized. But if you look at the source, they are, at least in the current implementation. So I don't think there's a problem to merge this PR. But we should still fix the issue you raised with libc.

@stevenengler
Copy link
Contributor

@stevenengler could you test your code with this PR please?

Yep, my example code works with this PR. Thanks for looking into this!

@asomers asomers added this to the 0.26.0 milestone Nov 21, 2022
@asomers
Copy link
Member Author

asomers commented Nov 21, 2022

bors r=rtzoeller

@bors bors bot merged commit 9ea1493 into nix-rust:master Nov 21, 2022
asomers added a commit to asomers/nix that referenced this pull request Nov 21, 2022
Use it in the from_sockaddr_un_abstract_unnamed test.  That test and
this method were introduced by PRs nix-rust#1871 and nix-rust#1857, which crossed each
other.
bors bot added a commit that referenced this pull request Nov 21, 2022
1880: Use the new UnixAddr::new_unnamed in the unit tests r=rtzoeller a=asomers

Use it in the from_sockaddr_un_abstract_unnamed test.  That test and this method were introduced by PRs #1871 and #1857, which crossed each other.

Co-authored-by: Alan Somers <asomers@gmail.com>
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.

SockaddrStorage broken for variable-length addresses
3 participants