When handing off a socket to a worker child, auditdistd sends a
variable-length string identifying the type of socket being passed. The
child tries to read that string into an oversized buffer, and then read
the socket itself with recvmsg. That used to work because the ancillary
data would interrupt the recv() call. But in FreeBSD 15.1, the recv()
call does a better job of honoring MSG_WAITALL, and does not get
interrupted. The result is a hang; recv() never returns because its
oversized buffer never fills up.
The the bug by omitting MSG_WAITALL when the receiver is expecting
ancillary data. Instead, read both the string and the ancillary data
with a single call to recvmsg(), looping if necessary.
PR: 296107
Reported by: Daniel Porsch <daniel.porsch@loopia.se>
Sponsored by: ConnectWise
MFC after: 1 week