Skip to content

Commit 06dbe83

Browse files
authored
Fix sendmsg_unix's address encoding. (#885) (#886)
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 00b84d6 commit 06dbe83

File tree

3 files changed

+135
-2
lines changed

3 files changed

+135
-2
lines changed

src/backend/libc/net/msghdr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub(crate) fn with_unix_msghdr<R>(
115115
) -> R {
116116
f({
117117
let mut h: c::msghdr = unsafe { zeroed() };
118-
h.msg_name = as_ptr(addr) as _;
118+
h.msg_name = as_ptr(&addr.unix) as _;
119119
h.msg_namelen = addr.addr_len();
120120
h.msg_iov = iov.as_ptr() as _;
121121
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
@@ -131,7 +131,7 @@ pub(crate) fn with_unix_msghdr<R>(
131131
f: impl FnOnce(c::msghdr) -> R,
132132
) -> R {
133133
f(c::msghdr {
134-
msg_name: as_ptr(addr) as _,
134+
msg_name: as_ptr(&addr.unix) as _,
135135
msg_namelen: addr.addr_len() as _,
136136
msg_iov: iov.as_ptr() as _,
137137
msg_iovlen: msg_iov_len(iov.len()),

tests/net/unix.rs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,113 @@ fn do_test_unix_msg(addr: SocketAddrUnix) {
283283
server.join().unwrap();
284284
}
285285

286+
/// Similar to `do_test_unix_msg` but uses an unconnected socket and
287+
/// `sendmsg_unix` instead of `sendmsg`.
288+
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
289+
fn do_test_unix_msg_unconnected(addr: SocketAddrUnix) {
290+
use rustix::io::{IoSlice, IoSliceMut};
291+
use rustix::net::{recvmsg, sendmsg_unix, RecvFlags, SendFlags};
292+
293+
let server = {
294+
let runs: &[i32] = &[3, 184, 187, 0];
295+
let data_socket =
296+
socket(AddressFamily::UNIX, SocketType::DGRAM, Default::default()).unwrap();
297+
bind_unix(&data_socket, &addr).unwrap();
298+
299+
move || {
300+
let mut buffer = vec![0; BUFFER_SIZE];
301+
for expected_sum in runs {
302+
let mut sum = 0;
303+
loop {
304+
let nread = recvmsg(
305+
&data_socket,
306+
&mut [IoSliceMut::new(&mut buffer)],
307+
&mut Default::default(),
308+
RecvFlags::empty(),
309+
)
310+
.unwrap()
311+
.bytes;
312+
313+
assert_ne!(&buffer[..nread], b"exit");
314+
if &buffer[..nread] == b"sum" {
315+
break;
316+
}
317+
318+
sum += i32::from_str(&String::from_utf8_lossy(&buffer[..nread])).unwrap();
319+
}
320+
321+
assert_eq!(sum, *expected_sum);
322+
}
323+
let nread = recvmsg(
324+
&data_socket,
325+
&mut [IoSliceMut::new(&mut buffer)],
326+
&mut Default::default(),
327+
RecvFlags::empty(),
328+
)
329+
.unwrap()
330+
.bytes;
331+
332+
assert_eq!(&buffer[..nread], b"exit");
333+
}
334+
};
335+
336+
let client = move || {
337+
let runs: &[&[&str]] = &[&["1", "2"], &["4", "77", "103"], &["5", "78", "104"], &[]];
338+
339+
for args in runs {
340+
let data_socket =
341+
socket(AddressFamily::UNIX, SocketType::DGRAM, Default::default()).unwrap();
342+
343+
for arg in *args {
344+
sendmsg_unix(
345+
&data_socket,
346+
&addr,
347+
&[IoSlice::new(arg.as_bytes())],
348+
&mut Default::default(),
349+
SendFlags::empty(),
350+
)
351+
.unwrap();
352+
}
353+
sendmsg_unix(
354+
&data_socket,
355+
&addr,
356+
&[IoSlice::new(b"sum")],
357+
&mut Default::default(),
358+
SendFlags::empty(),
359+
)
360+
.unwrap();
361+
}
362+
363+
let data_socket =
364+
socket(AddressFamily::UNIX, SocketType::DGRAM, Default::default()).unwrap();
365+
sendmsg_unix(
366+
&data_socket,
367+
&addr,
368+
&[IoSlice::new(b"exit")],
369+
&mut Default::default(),
370+
SendFlags::empty(),
371+
)
372+
.unwrap();
373+
};
374+
375+
let server = thread::Builder::new()
376+
.name("server".to_string())
377+
.spawn(move || {
378+
server();
379+
})
380+
.unwrap();
381+
382+
let client = thread::Builder::new()
383+
.name("client".to_string())
384+
.spawn(move || {
385+
client();
386+
})
387+
.unwrap();
388+
389+
client.join().unwrap();
390+
server.join().unwrap();
391+
}
392+
286393
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
287394
#[test]
288395
fn test_unix_msg() {
@@ -295,6 +402,19 @@ fn test_unix_msg() {
295402
unlinkat(cwd(), path, AtFlags::empty()).unwrap();
296403
}
297404

405+
/// Like `test_unix_msg` but tests `do_test_unix_msg_unconnected`.
406+
#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))]
407+
#[test]
408+
fn test_unix_msg_unconnected() {
409+
let tmpdir = tempfile::tempdir().unwrap();
410+
let path = tmpdir.path().join("scp_4804");
411+
412+
let name = SocketAddrUnix::new(&path).unwrap();
413+
do_test_unix_msg_unconnected(name);
414+
415+
unlinkat(cwd(), path, AtFlags::empty()).unwrap();
416+
}
417+
298418
#[cfg(linux_kernel)]
299419
#[test]
300420
fn test_abstract_unix_msg() {
@@ -307,6 +427,19 @@ fn test_abstract_unix_msg() {
307427
do_test_unix_msg(name);
308428
}
309429

430+
/// Like `test_abstract_unix_msg` but tests `do_test_unix_msg_unconnected`.
431+
#[cfg(linux_kernel)]
432+
#[test]
433+
fn test_abstract_unix_msg_unconnected() {
434+
use std::os::unix::ffi::OsStrExt;
435+
436+
let tmpdir = tempfile::tempdir().unwrap();
437+
let path = tmpdir.path().join("scp_4804");
438+
439+
let name = SocketAddrUnix::new_abstract_name(path.as_os_str().as_bytes()).unwrap();
440+
do_test_unix_msg_unconnected(name);
441+
}
442+
310443
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
311444
#[test]
312445
fn test_unix_msg_with_scm_rights() {

0 commit comments

Comments
 (0)