Skip to content

Commit 3758947

Browse files
authored
Fix c_char vs u8 errors in the linux_raw backend. (#971)
* Fix `c_char` vs `u8` errors in the linux_raw backend. Fix the linux_raw backend to handle the case where linux-raw-sys defines `c_char` as `i8`. linux-raw-sys used to always define `c_char` as `u8` because it usually isn't important to match the platform `char` type, but that makes it inconvenient to work with Rust's `CStr`/`CString` types which use `c_char`, so linux-raw-sys has started defining `c_char` as `i8` on platforms which define it that way. * Fix redundant `unsafe` blocks.
1 parent b1f8c8f commit 3758947

File tree

2 files changed

+44
-20
lines changed

2 files changed

+44
-20
lines changed

src/backend/linux_raw/net/addr.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::{io, path};
1212
use core::cmp::Ordering;
1313
use core::fmt;
1414
use core::hash::{Hash, Hasher};
15+
use core::slice;
1516

1617
/// `struct sockaddr_un`
1718
#[derive(Clone)]
@@ -36,7 +37,7 @@ impl SocketAddrUnix {
3637
return Err(io::Errno::NAMETOOLONG);
3738
}
3839
for (i, b) in bytes.iter().enumerate() {
39-
unix.sun_path[i] = *b;
40+
unix.sun_path[i] = *b as _;
4041
}
4142
let len = offsetof_sun_path() + bytes.len();
4243
let len = len.try_into().unwrap();
@@ -48,6 +49,10 @@ impl SocketAddrUnix {
4849
pub fn new_abstract_name(name: &[u8]) -> io::Result<Self> {
4950
let mut unix = Self::init();
5051
let id = &mut unix.sun_path[1..];
52+
53+
// SAFETY: Convert `&mut [c_char]` to `&mut [u8]`.
54+
let id = unsafe { slice::from_raw_parts_mut(id.as_mut_ptr().cast::<u8>(), id.len()) };
55+
5156
if let Some(id) = id.get_mut(..name.len()) {
5257
id.copy_from_slice(name);
5358
let len = offsetof_sun_path() + 1 + name.len();
@@ -69,9 +74,13 @@ impl SocketAddrUnix {
6974
#[inline]
7075
pub fn path(&self) -> Option<&CStr> {
7176
let len = self.len();
72-
if len != 0 && self.unix.sun_path[0] != b'\0' {
77+
if len != 0 && self.unix.sun_path[0] as u8 != b'\0' {
7378
let end = len as usize - offsetof_sun_path();
7479
let bytes = &self.unix.sun_path[..end];
80+
81+
// SAFETY: Convert `&[c_char]` to `&[u8]`.
82+
let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()) };
83+
7584
// SAFETY: `from_bytes_with_nul_unchecked` since the string is
7685
// NUL-terminated.
7786
unsafe { Some(CStr::from_bytes_with_nul_unchecked(bytes)) }
@@ -84,9 +93,14 @@ impl SocketAddrUnix {
8493
#[inline]
8594
pub fn abstract_name(&self) -> Option<&[u8]> {
8695
let len = self.len();
87-
if len != 0 && self.unix.sun_path[0] == b'\0' {
96+
if len != 0 && self.unix.sun_path[0] as u8 == b'\0' {
8897
let end = len as usize - offsetof_sun_path();
89-
Some(&self.unix.sun_path[1..end])
98+
let bytes = &self.unix.sun_path[1..end];
99+
100+
// SAFETY: Convert `&[c_char]` to `&[u8]`.
101+
let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len()) };
102+
103+
Some(bytes)
90104
} else {
91105
None
92106
}

src/backend/linux_raw/net/read_sockaddr.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::backend::c;
66
use crate::io;
77
use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6};
88
use core::mem::size_of;
9+
use core::slice;
910

1011
// This must match the header of `sockaddr`.
1112
#[repr(C)]
@@ -93,17 +94,22 @@ pub(crate) unsafe fn read_sockaddr(
9394
//
9495
// [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html
9596
if decode.sun_path[0] == 0 {
96-
return SocketAddrUnix::new_abstract_name(
97-
&decode.sun_path[1..len - offsetof_sun_path],
98-
)
99-
.map(SocketAddrAny::Unix);
97+
let bytes = &decode.sun_path[1..len - offsetof_sun_path];
98+
99+
// SAFETY: Convert `&[c_char]` to `&[u8]`.
100+
let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len());
101+
102+
return SocketAddrUnix::new_abstract_name(bytes).map(SocketAddrAny::Unix);
100103
}
101104

102105
// Otherwise we expect a NUL-terminated filesystem path.
106+
let bytes = &decode.sun_path[..len - 1 - offsetof_sun_path];
107+
108+
// SAFETY: Convert `&[c_char]` to `&[u8]`.
109+
let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len());
110+
103111
assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0);
104-
Ok(SocketAddrAny::Unix(SocketAddrUnix::new(
105-
&decode.sun_path[..len - 1 - offsetof_sun_path],
106-
)?))
112+
Ok(SocketAddrAny::Unix(SocketAddrUnix::new(bytes)?))
107113
}
108114
}
109115
_ => Err(io::Errno::NOTSUP),
@@ -165,19 +171,23 @@ pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) -
165171
//
166172
// [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html
167173
if decode.sun_path[0] == 0 {
168-
return SocketAddrAny::Unix(
169-
SocketAddrUnix::new_abstract_name(
170-
&decode.sun_path[1..len - offsetof_sun_path],
171-
)
172-
.unwrap(),
173-
);
174+
let bytes = &decode.sun_path[1..len - offsetof_sun_path];
175+
176+
// SAFETY: Convert `&[c_char]` to `&[u8]`.
177+
let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len());
178+
179+
return SocketAddrAny::Unix(SocketAddrUnix::new_abstract_name(bytes).unwrap());
174180
}
175181

176182
// Otherwise we expect a NUL-terminated filesystem path.
177183
assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0);
178-
SocketAddrAny::Unix(
179-
SocketAddrUnix::new(&decode.sun_path[..len - 1 - offsetof_sun_path]).unwrap(),
180-
)
184+
185+
let bytes = &decode.sun_path[..len - 1 - offsetof_sun_path];
186+
187+
// SAFETY: Convert `&[c_char]` to `&[u8]`.
188+
let bytes = slice::from_raw_parts(bytes.as_ptr().cast::<u8>(), bytes.len());
189+
190+
SocketAddrAny::Unix(SocketAddrUnix::new(bytes).unwrap())
181191
}
182192
}
183193
other => unimplemented!("{:?}", other),

0 commit comments

Comments
 (0)