Skip to content

Support recvmsg#777

Open
CvvT wants to merge 9 commits intomainfrom
weiteng/add_recvmsg
Open

Support recvmsg#777
CvvT wants to merge 9 commits intomainfrom
weiteng/add_recvmsg

Conversation

@CvvT
Copy link
Copy Markdown
Contributor

@CvvT CvvT commented Apr 15, 2026

Support syscall recvmsg.

Some flags like MSG_PEEK is not supported yet but can be added when needed.

Also fix a message boundary issue for datagram unix socket, i.e., one read should only read one message.

@CvvT CvvT marked this pull request as ready for review April 15, 2026 22:49
Comment on lines +1598 to +1612
let size = self.do_recvfrom(
sockfd,
recv_buf,
flags,
if want_source {
Some(&mut source_addr)
} else {
None
},
)?;

// Set MSG_TRUNC if the received message was larger than the total buffer.
if size > total_iov_capacity {
ret_flags |= ReceiveFlags::TRUNC;
}
Copy link
Copy Markdown
Contributor

@sangho2 sangho2 May 7, 2026

Choose a reason for hiding this comment

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

High: recvmsg does not set output MSG_TRUNC for truncated datagrams.
this calls do_recvfrom without forcing MSG_TRUNC, then sets msg_flags only when size > total_iov_capacity. For datagram sockets, do_recvfrom returns the copied length unless the caller passed input MSG_TRUNC, so a too-large datagram received without input MSG_TRUNC returns the copied byte count but leaves msg_flags empty. Linux recvmsg should set msg_flags |= MSG_TRUNC when the datagram was larger than the supplied iovecs.

It sounds like size cannot be greater than total_iov_capacity for datagrams received without MSG_TRUNC even if there was truncation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is checked at

let total_received = if flags.contains(ReceiveFlags::TRUNC) {
// the actual message size
size
} else {
// the number of bytes copied
size.min(total_iov_capacity)
};

Comment thread litebox_shim_linux/src/syscalls/net.rs Outdated
Comment on lines +1573 to +1588
if msg_iovlen == 0 || msg_iovlen > 1024 {
return Err(Errno::EINVAL);
}

let iovs = msg_iov.to_owned_slice(msg_iovlen).ok_or(Errno::EFAULT)?;

// Compute total buffer capacity across all non-empty iovecs, capped at MAX_LEN.
let total_iov_capacity: usize = iovs
.iter()
.map(|iov| iov.iov_len)
.fold(0usize, usize::saturating_add)
.min(MAX_LEN);

if total_iov_capacity == 0 {
return Ok(0);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

High: zero-length recvmsg is incorrect.
This rejects msg_iovlen == 0 with EINVAL, and returns 0 immediately when total iovec capacity is zero. Linux permits zero-length receives. For datagram sockets, a zero-length receive can still dequeue one pending datagram and should update output fields such as msg_flags, msg_namelen, and msg_controllen.

It sounds like LiteBox might not dequeue pending zero-length datagram?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right, I added a test to confirm that's Linux's behavior. It is fixed now.

@CvvT CvvT force-pushed the weiteng/add_recvmsg branch from 5441699 to 0d5cb58 Compare May 9, 2026 01:04
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

🤖 SemverChecks 🤖 ⚠️ Potential breaking API changes detected ⚠️

Click for details
--- failure enum_no_repr_variant_discriminant_changed: enum variant had its discriminant change value ---

Description:
The enum's variant had its discriminant value change. This breaks downstream code that used its value via a numeric cast like `as isize`.
        ref: https://doc.rust-lang.org/reference/items/enumerations.html#assigning-discriminant-values
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_no_repr_variant_discriminant_changed.ron

Failed in:
  variant SyscallRequest::Bind 38 -> 39 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1919
  variant SyscallRequest::Listen 39 -> 40 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1924
  variant SyscallRequest::Setsockopt 40 -> 41 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1928
  variant SyscallRequest::Getsockopt 41 -> 42 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1935
  variant SyscallRequest::Getsockname 42 -> 43 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1942
  variant SyscallRequest::Getpeername 43 -> 44 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1947
  variant SyscallRequest::Uname 44 -> 45 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1952
  variant SyscallRequest::Fcntl 45 -> 46 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1955
  variant SyscallRequest::Getcwd 46 -> 47 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1959
  variant SyscallRequest::EpollCtl 47 -> 48 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1963
  variant SyscallRequest::EpollPwait 48 -> 49 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1969
  variant SyscallRequest::EpollCreate 49 -> 50 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1977
  variant SyscallRequest::Ppoll 50 -> 51 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1981
  variant SyscallRequest::Pselect 51 -> 52 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1988
  variant SyscallRequest::ArchPrctl 52 -> 53 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1996
  variant SyscallRequest::Readlink 53 -> 54 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:1999
  variant SyscallRequest::Readlinkat 54 -> 55 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2004
  variant SyscallRequest::Openat 55 -> 56 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2010
  variant SyscallRequest::Ftruncate 56 -> 57 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2016
  variant SyscallRequest::Unlinkat 57 -> 58 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2020
  variant SyscallRequest::Newfstatat 58 -> 59 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2026
  variant SyscallRequest::Eventfd2 59 -> 60 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2032
  variant SyscallRequest::Pipe2 60 -> 61 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2036
  variant SyscallRequest::Clone 61 -> 62 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2040
  variant SyscallRequest::Clone3 62 -> 63 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2043
  variant SyscallRequest::SetThreadArea 63 -> 64 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2048
  variant SyscallRequest::ClockGettime 64 -> 65 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2051
  variant SyscallRequest::ClockGetres 65 -> 66 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2055
  variant SyscallRequest::ClockNanosleep 66 -> 67 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2059
  variant SyscallRequest::Gettimeofday 67 -> 68 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2065
  variant SyscallRequest::Time 68 -> 69 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2069
  variant SyscallRequest::Getrlimit 69 -> 70 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2072
  variant SyscallRequest::Setrlimit 70 -> 71 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2076
  variant SyscallRequest::Prlimit 71 -> 72 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2080
  variant SyscallRequest::SetTidAddress 72 -> 73 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2091
  variant SyscallRequest::Gettid 73 -> 74 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2094
  variant SyscallRequest::SetRobustList 74 -> 75 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2095
  variant SyscallRequest::GetRobustList 75 -> 76 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2098
  variant SyscallRequest::GetRandom 76 -> 77 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2103
  variant SyscallRequest::Getpid 77 -> 78 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2108
  variant SyscallRequest::Getppid 78 -> 79 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2109
  variant SyscallRequest::Getuid 79 -> 80 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2110
  variant SyscallRequest::Geteuid 80 -> 81 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2111
  variant SyscallRequest::Getgid 81 -> 82 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2112
  variant SyscallRequest::Getegid 82 -> 83 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2113
  variant SyscallRequest::Sysinfo 83 -> 84 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2114
  variant SyscallRequest::CapGet 84 -> 85 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2117
  variant SyscallRequest::GetDirent64 85 -> 86 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2121
  variant SyscallRequest::SchedGetAffinity 86 -> 87 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2126
  variant SyscallRequest::SchedYield 87 -> 88 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2131
  variant SyscallRequest::Futex 88 -> 89 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2132
  variant SyscallRequest::Execve 89 -> 90 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2135
  variant SyscallRequest::Umask 90 -> 91 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2140
  variant SyscallRequest::Prctl 91 -> 92 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2143
  variant SyscallRequest::Alarm 92 -> 93 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2146
  variant SyscallRequest::SetITimer 93 -> 94 in /home/runner/work/litebox/litebox/litebox_common_linux/src/lib.rs:2149

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.

2 participants