Skip to content

Commit a59a191

Browse files
authored
Fix sendmsg_unix's address encoding. (#885)
When encoding the address for `sendmsg_unix`, use the `unix` field of `SocketAddrUnix`, since the `unix` field is the `sockaddr_un` that the OS will read. Fixes #884.
1 parent e35481c commit a59a191

3 files changed

Lines changed: 132 additions & 2 deletions

File tree

src/backend/libc/net/msghdr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub(crate) fn with_unix_msghdr<R>(
114114
) -> R {
115115
f({
116116
let mut h = zero_msghdr();
117-
h.msg_name = as_ptr(addr) as _;
117+
h.msg_name = as_ptr(&addr.unix) as _;
118118
h.msg_namelen = addr.addr_len();
119119
h.msg_iov = iov.as_ptr() as _;
120120
h.msg_iovlen = msg_iov_len(iov.len());

src/backend/linux_raw/net/msghdr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub(crate) fn with_unix_msghdr<R>(
122122
f: impl FnOnce(c::msghdr) -> R,
123123
) -> R {
124124
f(c::msghdr {
125-
msg_name: as_ptr(addr) as _,
125+
msg_name: as_ptr(&addr.unix) as _,
126126
msg_namelen: addr.addr_len() as _,
127127
msg_iov: iov.as_ptr() as _,
128128
msg_iovlen: msg_iov_len(iov.len()),

tests/net/unix.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,110 @@ fn do_test_unix_msg(addr: SocketAddrUnix) {
253253
server.join().unwrap();
254254
}
255255

256+
/// Similar to `do_test_unix_msg` but uses an unconnected socket and
257+
/// `sendmsg_unix` instead of `sendmsg`.
258+
#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))]
259+
fn do_test_unix_msg_unconnected(addr: SocketAddrUnix) {
260+
use rustix::io::{IoSlice, IoSliceMut};
261+
use rustix::net::{recvmsg, sendmsg_unix, RecvFlags, SendFlags};
262+
263+
let server = {
264+
let runs: &[i32] = &[3, 184, 187, 0];
265+
let data_socket = socket(AddressFamily::UNIX, SocketType::DGRAM, None).unwrap();
266+
bind_unix(&data_socket, &addr).unwrap();
267+
268+
move || {
269+
let mut buffer = vec![0; BUFFER_SIZE];
270+
for expected_sum in runs {
271+
let mut sum = 0;
272+
loop {
273+
let nread = recvmsg(
274+
&data_socket,
275+
&mut [IoSliceMut::new(&mut buffer)],
276+
&mut Default::default(),
277+
RecvFlags::empty(),
278+
)
279+
.unwrap()
280+
.bytes;
281+
282+
assert_ne!(&buffer[..nread], b"exit");
283+
if &buffer[..nread] == b"sum" {
284+
break;
285+
}
286+
287+
sum += i32::from_str(&String::from_utf8_lossy(&buffer[..nread])).unwrap();
288+
}
289+
290+
assert_eq!(sum, *expected_sum);
291+
}
292+
let nread = recvmsg(
293+
&data_socket,
294+
&mut [IoSliceMut::new(&mut buffer)],
295+
&mut Default::default(),
296+
RecvFlags::empty(),
297+
)
298+
.unwrap()
299+
.bytes;
300+
301+
assert_eq!(&buffer[..nread], b"exit");
302+
}
303+
};
304+
305+
let client = move || {
306+
let runs: &[&[&str]] = &[&["1", "2"], &["4", "77", "103"], &["5", "78", "104"], &[]];
307+
308+
for args in runs {
309+
let data_socket = socket(AddressFamily::UNIX, SocketType::DGRAM, None).unwrap();
310+
311+
for arg in *args {
312+
sendmsg_unix(
313+
&data_socket,
314+
&addr,
315+
&[IoSlice::new(arg.as_bytes())],
316+
&mut Default::default(),
317+
SendFlags::empty(),
318+
)
319+
.unwrap();
320+
}
321+
sendmsg_unix(
322+
&data_socket,
323+
&addr,
324+
&[IoSlice::new(b"sum")],
325+
&mut Default::default(),
326+
SendFlags::empty(),
327+
)
328+
.unwrap();
329+
}
330+
331+
let data_socket = socket(AddressFamily::UNIX, SocketType::DGRAM, None).unwrap();
332+
sendmsg_unix(
333+
&data_socket,
334+
&addr,
335+
&[IoSlice::new(b"exit")],
336+
&mut Default::default(),
337+
SendFlags::empty(),
338+
)
339+
.unwrap();
340+
};
341+
342+
let server = thread::Builder::new()
343+
.name("server".to_string())
344+
.spawn(move || {
345+
server();
346+
})
347+
.unwrap();
348+
349+
let client = thread::Builder::new()
350+
.name("client".to_string())
351+
.spawn(move || {
352+
client();
353+
})
354+
.unwrap();
355+
356+
client.join().unwrap();
357+
server.join().unwrap();
358+
}
359+
256360
#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))]
257361
#[test]
258362
fn test_unix_msg() {
@@ -265,6 +369,19 @@ fn test_unix_msg() {
265369
unlinkat(CWD, path, AtFlags::empty()).unwrap();
266370
}
267371

372+
/// Like `test_unix_msg` but tests `do_test_unix_msg_unconnected`.
373+
#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))]
374+
#[test]
375+
fn test_unix_msg_unconnected() {
376+
let tmpdir = tempfile::tempdir().unwrap();
377+
let path = tmpdir.path().join("scp_4804");
378+
379+
let name = SocketAddrUnix::new(&path).unwrap();
380+
do_test_unix_msg_unconnected(name);
381+
382+
unlinkat(CWD, path, AtFlags::empty()).unwrap();
383+
}
384+
268385
#[cfg(linux_kernel)]
269386
#[test]
270387
fn test_abstract_unix_msg() {
@@ -277,6 +394,19 @@ fn test_abstract_unix_msg() {
277394
do_test_unix_msg(name);
278395
}
279396

397+
/// Like `test_abstract_unix_msg` but tests `do_test_unix_msg_unconnected`.
398+
#[cfg(linux_kernel)]
399+
#[test]
400+
fn test_abstract_unix_msg_unconnected() {
401+
use std::os::unix::ffi::OsStrExt;
402+
403+
let tmpdir = tempfile::tempdir().unwrap();
404+
let path = tmpdir.path().join("scp_4804");
405+
406+
let name = SocketAddrUnix::new_abstract_name(path.as_os_str().as_bytes()).unwrap();
407+
do_test_unix_msg_unconnected(name);
408+
}
409+
280410
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
281411
#[test]
282412
fn test_unix_msg_with_scm_rights() {

0 commit comments

Comments
 (0)