diff --git a/src/header/grp/mod.rs b/src/header/grp/mod.rs index 05478230ff..d9e5212022 100644 --- a/src/header/grp/mod.rs +++ b/src/header/grp/mod.rs @@ -118,19 +118,37 @@ impl OwnedGrp { } fn split(buf: &mut [u8]) -> Option { - let gid = match buf[0..mem::size_of::()].try_into() { + let gr_gid = match buf[0..mem::size_of::()].try_into() { Ok(buf) => gid_t::from_ne_bytes(buf), Err(err) => return None, }; + // Get address of buffer for fixing up gr_mem + let buf_addr = buf.as_ptr() as usize; + // We moved the gid to the beginning of the byte buffer so we can do this. let mut parts = buf[mem::size_of::()..].split_mut(|&c| c == b'\0'); + let gr_name = parts.next()?.as_mut_ptr() as *mut c_char; + let gr_passwd = parts.next()?.as_mut_ptr() as *mut c_char; + let gr_mem = parts.next()?.as_mut_ptr() as *mut usize; + + // Adjust gr_mem address by buffer base address + // TODO: max group members length? + for i in 0..4096 { + unsafe { + if *gr_mem.add(i) == 0 { + // End of gr_mem pointer array + break; + } + *gr_mem.add(i) += buf_addr; + } + } Some(group { - gr_name: parts.next()?.as_mut_ptr() as *mut i8, - gr_passwd: parts.next()?.as_mut_ptr() as *mut i8, - gr_gid: gid, - gr_mem: parts.next()?.as_mut_ptr() as *mut *mut c_char, // this will work because this points to the first string, which also happens to be the start of the array. The two are equivalent, just need to by typecast. + gr_name, + gr_passwd, + gr_gid, + gr_mem: gr_mem as *mut *mut c_char, }) } @@ -167,18 +185,36 @@ fn parse_grp(line: String, destbuf: Option) -> Result 0) + .filter(|member| !member.is_empty()) { - vec.extend(i.to_vec()); + vec.extend(0usize.to_ne_bytes()); + } + // Push a null pointer to terminate the members array + vec.extend(0usize.to_ne_bytes()); + + // Fill in member names + for (i, member) in members + .split(|b| *b == b',') + .filter(|member| !member.is_empty()) + .enumerate() + { + // Store offset to start of member, MUST BE ADJUSTED LATER BASED ON THE ADDRESS OF THE BUFFER + unsafe { + *member_array_ptr.add(i) = vec.len(); + } + + vec.extend(member); vec.push(0); } - vec.extend(0usize.to_ne_bytes()); - vec };