summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sys/mman.rs21
-rw-r--r--src/unistd.rs8
-rw-r--r--test/sys/test_mman.rs14
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)
};