diff --git a/CHANGELOG.md b/CHANGELOG.md index f81268a0e5..ec3dc7c39f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,9 +91,10 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Added more errno definitions for better backwards compatibility with Nix 0.21.0. (#[1467](https://github.com/nix-rust/nix/pull/1467)) - - Fixed potential undefined behavior in `Signal::try_from` on some platforms. (#[1484](https://github.com/nix-rust/nix/pull/1484)) +- Fixed buffer overflow in `unistd::getgrouplist`. + (#[1545](https://github.com/nix-rust/nix/pull/1545)) ### Removed diff --git a/src/unistd.rs b/src/unistd.rs index 64759dc6bd..a9862d37a3 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1540,8 +1540,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { Ok(None) | Err(_) => ::max_value(), }; use std::cmp::min; - let mut ngroups = min(ngroups_max, 8); - let mut groups = Vec::::with_capacity(ngroups as usize); + let mut groups = Vec::::with_capacity(min(ngroups_max, 8) as usize); cfg_if! { if #[cfg(any(target_os = "ios", target_os = "macos"))] { type getgrouplist_group_t = c_int; @@ -1551,6 +1550,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result> { } let gid: gid_t = group.into(); loop { + let mut ngroups = groups.capacity() as i32; let ret = unsafe { libc::getgrouplist(user.as_ptr(), gid as getgrouplist_group_t,