diff options
-rw-r--r-- | src/sys/mman.rs | 21 | ||||
-rw-r--r-- | src/unistd.rs | 8 | ||||
-rw-r--r-- | test/sys/test_mman.rs | 14 |
3 files changed, 39 insertions, 4 deletions
diff --git a/src/sys/mman.rs b/src/sys/mman.rs index 908900ca..ba6eb661 100644 --- a/src/sys/mman.rs +++ b/src/sys/mman.rs @@ -139,14 +139,22 @@ libc_bitflags!{ } } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "netbsd"))] libc_bitflags!{ /// Options for `mremap()`. pub struct MRemapFlags: c_int { /// Permit the kernel to relocate the mapping to a new virtual address, if necessary. + #[cfg(target_os = "linux")] MREMAP_MAYMOVE; /// Place the mapping at exactly the address specified in `new_address`. + #[cfg(target_os = "linux")] MREMAP_FIXED; + /// Permits to use the old and new address as hints to relocate the mapping. + #[cfg(target_os = "netbsd")] + MAP_FIXED; + /// Allows to duplicate the mapping to be able to apply different flags on the copy. + #[cfg(target_os = "netbsd")] + MAP_REMAPDUP; } } @@ -334,7 +342,7 @@ pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: Ma /// /// See the `mremap(2)` [man page](https://man7.org/linux/man-pages/man2/mremap.2.html) for /// detailed requirements. -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "netbsd"))] pub unsafe fn mremap( addr: *mut c_void, old_size: size_t, @@ -342,7 +350,16 @@ pub unsafe fn mremap( flags: MRemapFlags, new_address: Option<* mut c_void>, ) -> Result<*mut c_void> { + #[cfg(target_os = "linux")] let ret = libc::mremap(addr, old_size, new_size, flags.bits(), new_address.unwrap_or(std::ptr::null_mut())); + #[cfg(target_os = "netbsd")] + let ret = libc::mremap( + addr, + old_size, + new_address.unwrap_or(std::ptr::null_mut()), + new_size, + flags.bits(), + ); if ret == libc::MAP_FAILED { Err(Error::from(Errno::last())) diff --git a/src/unistd.rs b/src/unistd.rs index 25b20051..2f47b260 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1420,6 +1420,14 @@ pub fn getgroups() -> Result<Vec<Gid>> { // Next, get the number of groups so we can size our Vec let ngroups = unsafe { libc::getgroups(0, ptr::null_mut()) }; + // If there are no supplementary groups, return early. + // This prevents a potential buffer over-read if the number of groups + // increases from zero before the next call. It would return the total + // number of groups beyond the capacity of the buffer. + if ngroups == 0 { + return Ok(Vec::new()); + } + // Now actually get the groups. We try multiple times in case the number of // groups has changed since the first call to getgroups() and the buffer is // now too small. diff --git a/test/sys/test_mman.rs b/test/sys/test_mman.rs index 152fff69..4d140948 100644 --- a/test/sys/test_mman.rs +++ b/test/sys/test_mman.rs @@ -20,7 +20,7 @@ fn test_mmap_anonymous() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "netbsd"))] fn test_mremap_grow() { const ONE_K : size_t = 1024; let slice : &mut[u8] = unsafe { @@ -35,9 +35,14 @@ fn test_mremap_grow() { assert_eq !(slice[ONE_K - 1], 0xFF); let slice : &mut[u8] = unsafe { + #[cfg(target_os = "linux")] let mem = mremap(slice.as_mut_ptr() as * mut c_void, ONE_K, 10 * ONE_K, MRemapFlags::MREMAP_MAYMOVE, None) .unwrap(); + #[cfg(target_os = "netbsd")] + let mem = mremap(slice.as_mut_ptr() as * mut c_void, ONE_K, 10 * ONE_K, + MRemapFlags::MAP_REMAPDUP, None) + .unwrap(); std::slice::from_raw_parts_mut(mem as * mut u8, 10 * ONE_K) }; @@ -51,7 +56,7 @@ fn test_mremap_grow() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "netbsd"))] fn test_mremap_shrink() { const ONE_K : size_t = 1024; let slice : &mut[u8] = unsafe { @@ -66,11 +71,16 @@ fn test_mremap_shrink() { assert_eq !(slice[ONE_K - 1], 0xFF); let slice : &mut[u8] = unsafe { + #[cfg(target_os = "linux")] let mem = mremap(slice.as_mut_ptr() as * mut c_void, 10 * ONE_K, ONE_K, MRemapFlags::empty(), None) .unwrap(); // Since we didn't supply MREMAP_MAYMOVE, the address should be the // same. + #[cfg(target_os = "linux")] + let mem = mremap(slice.as_mut_ptr() as * mut c_void, 10 * ONE_K, ONE_K, + MRemapFlags::MAP_FIXED), None) + .unwrap(); assert_eq !(mem, slice.as_mut_ptr() as * mut c_void); std::slice::from_raw_parts_mut(mem as * mut u8, ONE_K) }; |