Skip to content

Does usage of as_raw_mut_general violate provenance? #31

Description

@Manishearth

I'm not actually sure how the provenance model works here when syscalls/libc are involved.

as_raw_mut_reference narrows a sockaddr_un into a &mut sockaddr (smaller)

uds/src/addr.rs

Lines 773 to 776 in f17ebbb

pub unsafe fn as_raw_mut_general(&mut self) -> (&mut sockaddr, &mut socklen_t) {
// SAFETY: sockaddr is a super-type of sockaddr_un.
(&mut*(&mut self.addr as *mut sockaddr_un as *mut sockaddr), &mut self.len)
}

uds/src/addr.rs

Line 652 in f17ebbb

let (addr_ptr, addr_len_ptr) = addr.as_raw_mut_general();

uds/src/traits.rs

Lines 285 to 298 in f17ebbb

fn recv_from_unix_addr(&self, buf: &mut[u8]) -> Result<(usize, UnixSocketAddr), io::Error> {
UnixSocketAddr::new_from_ffi(|addr, len| {
unsafe {
cvt_r!(recvfrom(
self.as_raw_fd(),
buf.as_ptr() as *mut c_void,
buf.len(),
MSG_NOSIGNAL,
addr,
len,
)).map(|signed| signed as usize )
}
})
}

However we know that C calls on the other side like recvfrom will be re-widening sockaddr to sockaddr_un. Is that actually sound, provenance-wise? Would Rust be making assumptions that the overall sockaddr_un won't be mutated?

I assume this is actually okay, since I can't imagine how this API is supposed to work otherwise, but I want to somewhat flag this. I know there are some discussions about C also getting a strict provenance-like model.

Filing the issue here but probably worth filing on unsafe-code-guidelines eventually.

cc @RalfJung

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions