Merge branch 'p3' into 'main'
fix(ipcd/uds/stream): handle zero-byte payload See merge request redox-os/base!69
This commit is contained in:
+30
-43
@@ -405,12 +405,14 @@ impl<'sock> UdsStreamScheme<'sock> {
|
||||
self.sockets.get(&id).ok_or(Error::new(EBADF))
|
||||
}
|
||||
|
||||
fn get_connected_peer(&self, id: usize) -> Result<(usize, Rc<RefCell<Socket>>), Error> {
|
||||
fn get_connected_peer(
|
||||
&self,
|
||||
id: usize,
|
||||
flags: MsgFlags,
|
||||
) -> Result<(usize, Rc<RefCell<Socket>>), Error> {
|
||||
let mut socket = self.get_socket(id)?.borrow_mut();
|
||||
|
||||
let remote_id = socket
|
||||
.require_connected_connection(MsgFlags::default())?
|
||||
.peer;
|
||||
let remote_id = socket.require_connected_connection(flags)?.peer;
|
||||
let remote_rc = self.get_socket(remote_id).map_err(|e| {
|
||||
eprintln!("get_connected_peer(id: {}): Peer socket (id: {}) has vanished. Original error: {:?}", id, remote_id, e);
|
||||
Error::new(EPIPE)
|
||||
@@ -652,7 +654,7 @@ impl<'sock> UdsStreamScheme<'sock> {
|
||||
match option {
|
||||
libc::SO_DOMAIN => write_value(&AF_UNIX.to_le_bytes()),
|
||||
libc::SO_PEERCRED => {
|
||||
let (_, remote_rc) = self.get_connected_peer(id)?;
|
||||
let (_, remote_rc) = self.get_connected_peer(id, MsgFlags::default())?;
|
||||
let remote = remote_rc.borrow();
|
||||
write_value(unsafe {
|
||||
slice::from_raw_parts(
|
||||
@@ -690,49 +692,34 @@ impl<'sock> UdsStreamScheme<'sock> {
|
||||
|
||||
let (bytes_written, remote_id) = {
|
||||
let name = self.get_socket(id)?.borrow().path.clone();
|
||||
let (remote_id, remote_rc) = self.get_connected_peer(id)?;
|
||||
let (remote_id, remote_rc) = self.get_connected_peer(id, msg_flags)?;
|
||||
let mut socket = remote_rc.borrow_mut();
|
||||
let connection = socket.require_connected_connection(msg_flags)?;
|
||||
let (pid, uid, gid) = get_uid_gid_from_pid(self.proc_creds_capability, ctx.pid)?;
|
||||
|
||||
let bytes_written = Self::sendmsg_inner(
|
||||
self.proc_creds_capability,
|
||||
&mut remote_rc.borrow_mut(),
|
||||
name,
|
||||
msg_flags,
|
||||
let packet = DataPacket::from_stream(
|
||||
msg_stream,
|
||||
ctx,
|
||||
name,
|
||||
Credential::new(pid as i32, uid as i32, gid as i32),
|
||||
)?;
|
||||
(bytes_written, remote_id)
|
||||
|
||||
let payload_len = packet.len();
|
||||
|
||||
// sendmsg(2) on `SOCK_STREAM` with zero-byte payload is a no-op
|
||||
// even if ancillary data is present. Note that this does not apply
|
||||
// to `SOCK_DGRAM`.
|
||||
if payload_len == 0 {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
connection.packets.push_back(packet);
|
||||
(payload_len, remote_id)
|
||||
};
|
||||
|
||||
self.post_fevent(remote_id, EVENT_READ)?;
|
||||
Ok(bytes_written)
|
||||
}
|
||||
|
||||
fn sendmsg_inner(
|
||||
cap_fd: usize,
|
||||
socket: &mut Socket,
|
||||
name: Option<String>,
|
||||
msg_flags: MsgFlags,
|
||||
msg_stream: &[u8],
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<usize> {
|
||||
if msg_stream.is_empty() {
|
||||
eprintln!("sendmsg_inner: msg_stream is empty.");
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
let connection = socket.require_connected_connection(msg_flags)?;
|
||||
|
||||
let (pid, uid, gid) = get_uid_gid_from_pid(cap_fd, ctx.pid)?;
|
||||
let packet = DataPacket::from_stream(
|
||||
msg_stream,
|
||||
name,
|
||||
Credential::new(pid as i32, uid as i32, gid as i32),
|
||||
)?;
|
||||
let payload_len = packet.len();
|
||||
connection.packets.push_back(packet);
|
||||
|
||||
Ok(payload_len)
|
||||
}
|
||||
|
||||
fn handle_recvmsg(
|
||||
&mut self,
|
||||
id: usize,
|
||||
@@ -834,7 +821,7 @@ impl<'sock> UdsStreamScheme<'sock> {
|
||||
}
|
||||
|
||||
fn handle_get_peer_name(&self, id: usize, payload: &mut [u8]) -> Result<usize> {
|
||||
let (_, socket_rc) = self.get_connected_peer(id)?;
|
||||
let (_, socket_rc) = self.get_connected_peer(id, MsgFlags::default())?;
|
||||
let socket_borrow = socket_rc.borrow();
|
||||
match socket_borrow.path.as_ref() {
|
||||
Some(path_string) => Self::fpath_inner(path_string, payload),
|
||||
@@ -1246,7 +1233,7 @@ impl<'sock> SchemeSync for UdsStreamScheme<'sock> {
|
||||
_flags: u32,
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<usize> {
|
||||
let (receiver_id, _) = self.get_connected_peer(id)?;
|
||||
let (receiver_id, _) = self.get_connected_peer(id, MsgFlags::default())?;
|
||||
self.write_inner(receiver_id, buf, ctx)
|
||||
}
|
||||
|
||||
@@ -1286,7 +1273,7 @@ impl<'sock> SchemeSync for UdsStreamScheme<'sock> {
|
||||
|
||||
fn on_sendfd(&mut self, sendfd_request: &SendFdRequest) -> Result<usize> {
|
||||
let id = sendfd_request.id();
|
||||
let (receiver_id, _) = self.get_connected_peer(id)?;
|
||||
let (receiver_id, _) = self.get_connected_peer(id, MsgFlags::default())?;
|
||||
|
||||
self.sendfd_inner(receiver_id, sendfd_request)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user