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

Set unix socket permission prior to bind #111

Open
chipsenkbeil opened this issue Jul 19, 2022 · 2 comments
Open

Set unix socket permission prior to bind #111

chipsenkbeil opened this issue Jul 19, 2022 · 2 comments
Labels
bug Something isn't working
Milestone

Comments

@chipsenkbeil
Copy link
Owner

Tokio tracking issue: tokio-rs/tokio#4422

Example of how to do this with libc and socket2: https://github.com/stackabletech/secret-operator/pull/26/files

Neither tokio nor the std library supports this, which leaves a temporary moment where the socket is world-accessible. By default, we want the permission to be 0o600 (only owner readable and writeable) with the option to configure as 0o666 (anyone can read and write) for looser access.

@chipsenkbeil chipsenkbeil added the bug Something isn't working label Jul 19, 2022
@chipsenkbeil chipsenkbeil added this to the 1.0 milestone Jul 19, 2022
@chipsenkbeil
Copy link
Owner Author

// Workaround for https://github.com/tokio-rs/tokio/issues/4422
let socket = Socket::new(socket2::Domain::UNIX, socket2::Type::STREAM, None)?;
unsafe {
    // Socket-level chmod is propagated to the file created by Socket::bind.
    // We need to chmod /before/ creating the file, because otherwise there is a brief window where
    // the file is world-accessible (unless restricted by the global umask).
    if libc::fchmod(socket.as_raw_fd(), 0o600) == -1 {
        return Err(std::io::Error::last_os_error());
    }
}
socket.bind(&socket2::SockAddr::unix(path)?)?;
socket.listen(1024)?;
UnixListener::from_std(socket.into())

@stevenengler
Copy link

stevenengler commented Apr 25, 2024

// Workaround for https://github.com/tokio-rs/tokio/issues/4422
let socket = Socket::new(socket2::Domain::UNIX, socket2::Type::STREAM, None)?;
unsafe {
    // Socket-level chmod is propagated to the file created by Socket::bind.
    // We need to chmod /before/ creating the file, because otherwise there is a brief window where
    // the file is world-accessible (unless restricted by the global umask).
    if libc::fchmod(socket.as_raw_fd(), 0o600) == -1 {
        return Err(std::io::Error::last_os_error());
    }
}
socket.bind(&socket2::SockAddr::unix(path)?)?;
socket.listen(1024)?;
UnixListener::from_std(socket.into())

Just passing by through linked GitHub issues, but figured I'd mention that you'll also need to manually set the socket as non-blocking.

https://docs.rs/tokio/latest/tokio/net/struct.UnixListener.html

The caller is responsible for ensuring that the listener is in non-blocking mode. Otherwise all I/O operations on the listener will block the thread, which will cause unexpected behavior. Non-blocking mode can be set using set_nonblocking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants