diff --git a/CHANGELOG.md b/CHANGELOG.md index 558733d810..5982d70c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,11 @@ This project adheres to [Semantic Versioning](https://semver.org/). ([#1804](https://github.com/nix-rust/nix/pull/1804)) - Added `line_discipline` field to `Termios` on Linux, Android and Haiku ([#1805](https://github.com/nix-rust/nix/pull/1805)) +- Expose the memfd module on FreeBSD (memfd was added in FreeBSD 13) + ([#1808](https://github.com/nix-rust/nix/pull/1808)) - Added `domainname` field of `UtsName` on Android and Linux ([#1817](https://github.com/nix-rust/nix/pull/1817)) - + ### Changed - The MSRV is now 1.56.1 @@ -22,6 +24,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Fix microsecond calculation for `TimeSpec`. ([#1801](https://github.com/nix-rust/nix/pull/1801)) +- Fix `User::from_name` and `Group::from_name` panicking + when given a name containing a nul. + ([#1815](https://github.com/nix-rust/nix/pull/1815)) ### Removed diff --git a/src/fcntl.rs b/src/fcntl.rs index 160b022d77..650828345b 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -809,9 +809,7 @@ pub fn fspacectl_all(fd: RawFd, offset: libc::off_t, len: libc::off_t) 0, // No flags are currently supported &mut rqsr )}; - if let Err(e) = Errno::result(res) { - return Err(e); - } + Errno::result(res)?; } Ok(()) } diff --git a/src/sys/memfd.rs b/src/sys/memfd.rs index 642676b431..9f08dbb2bf 100644 --- a/src/sys/memfd.rs +++ b/src/sys/memfd.rs @@ -1,6 +1,8 @@ //! Interfaces for managing memory-backed files. use std::os::unix::io::RawFd; +use cfg_if::cfg_if; + use crate::Result; use crate::errno::Errno; use std::ffi::CStr; @@ -40,7 +42,22 @@ libc_bitflags!( /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result { let res = unsafe { - libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits()) + cfg_if! { + if #[cfg(all( + // Android does not have a memfd_create symbol + not(target_os = "android"), + any( + target_os = "freebsd", + // If the OS is Linux, gnu and musl expose a memfd_create symbol but not uclibc + target_env = "gnu", + target_env = "musl", + )))] + { + libc::memfd_create(name.as_ptr(), flags.bits()) + } else { + libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits()) + } + } }; Errno::result(res).map(|r| r as RawFd) diff --git a/src/sys/mod.rs b/src/sys/mod.rs index 979d623b89..2065059de8 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -50,7 +50,7 @@ feature! { #[macro_use] pub mod ioctl; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] feature! { #![feature = "fs"] pub mod memfd; diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index ecbf30ad44..6677420551 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1459,7 +1459,7 @@ pub fn sendmsg(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage], // because subsequent code will not clear the padding bytes. let mut cmsg_buffer = vec![0u8; capacity]; - let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], &iov, &cmsgs, addr); + let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], iov, cmsgs, addr); let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) }; diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 1cbb223ece..b3828b316f 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -816,7 +816,7 @@ struct SetBool { impl<'a> Set<'a, bool> for SetBool { fn new(val: &'a bool) -> SetBool { - SetBool { val: if *val { 1 } else { 0 } } + SetBool { val: i32::from(*val) } } fn ffi_ptr(&self) -> *const c_void { diff --git a/src/unistd.rs b/src/unistd.rs index 02fe4ff68e..63795cac22 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -3143,7 +3143,10 @@ impl User { /// assert_eq!(res.name, "root"); /// ``` pub fn from_name(name: &str) -> Result> { - let name = CString::new(name).unwrap(); + let name = match CString::new(name) { + Ok(c_str) => c_str, + Err(_nul_error) => return Ok(None), + }; User::from_anything(|pwd, cbuf, cap, res| { unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) } }) @@ -3268,7 +3271,10 @@ impl Group { /// assert!(res.name == "root"); /// ``` pub fn from_name(name: &str) -> Result> { - let name = CString::new(name).unwrap(); + let name = match CString::new(name) { + Ok(c_str) => c_str, + Err(_nul_error) => return Ok(None), + }; Group::from_anything(|grp, cbuf, cap, res| { unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) } }) diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index f4adee21fc..bc65b2601a 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -216,7 +216,7 @@ fn test_readlink() { let src = tempdir.path().join("a"); let dst = tempdir.path().join("b"); println!("a: {:?}, b: {:?}", &src, &dst); - fs::symlink(&src.as_path(), &dst.as_path()).unwrap(); + fs::symlink(src.as_path(), dst.as_path()).unwrap(); let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); let expected_dir = src.to_str().unwrap();