chipsenkbeil / distant

🚧 (Alpha stage software) Library and tooling that supports remote filesystem and process operations. 🚧
https://distant.dev
566 stars 11 forks source link

Set unix socket permission prior to bind #111

Open chipsenkbeil opened 2 years ago

chipsenkbeil commented 2 years ago

Tokio tracking issue: https://github.com/tokio-rs/tokio/issues/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 commented 2 years ago
// 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 commented 5 months ago
// 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.