Skip to content
Snippets Groups Projects
Commit e6f94291 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Merge branch 'derick/fixes' into 'master'

Four distinct fixes for significant incorrectness bugs, as three small commits

See merge request !481
parents 90af0198 572f211b
No related branches found
No related tags found
No related merge requests found
...@@ -187,8 +187,8 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro ...@@ -187,8 +187,8 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro
let members = buffer.next().ok_or(Error::EOF)?; let members = buffer.next().ok_or(Error::EOF)?;
// Get the pointer to the members array // Get the offset of the members array
let member_array_ptr = unsafe { vec.as_mut_ptr().add(vec.len()) as *mut usize }; let member_array_start = vec.len();
// Push enough null pointers to fit all members // Push enough null pointers to fit all members
for _member in members for _member in members
...@@ -197,6 +197,7 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro ...@@ -197,6 +197,7 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro
{ {
vec.extend(0usize.to_ne_bytes()); vec.extend(0usize.to_ne_bytes());
} }
let member_array_end = vec.len();
// Push a null pointer to terminate the members array // Push a null pointer to terminate the members array
vec.extend(0usize.to_ne_bytes()); vec.extend(0usize.to_ne_bytes());
...@@ -206,10 +207,20 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro ...@@ -206,10 +207,20 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro
.filter(|member| !member.is_empty()) .filter(|member| !member.is_empty())
.enumerate() .enumerate()
{ {
let cur_offset = vec.len();
// This must be recomputed each time, because `vec` is undergoing extensions and so
// its backing memory might be reallocated and moved and its old memory deallocated.
let member_array = &mut vec[member_array_start..member_array_end];
let member_ptr = {
const SIZEOF_PTR: usize = mem::size_of::<*mut c_void>();
let start = i * SIZEOF_PTR;
let end = start + SIZEOF_PTR;
&mut member_array[start..end]
};
// Store offset to start of member, MUST BE ADJUSTED LATER BASED ON THE ADDRESS OF THE BUFFER // Store offset to start of member, MUST BE ADJUSTED LATER BASED ON THE ADDRESS OF THE BUFFER
unsafe { member_ptr.copy_from_slice(&cur_offset.to_ne_bytes());
*member_array_ptr.add(i) = vec.len();
}
vec.extend(member); vec.extend(member);
vec.push(0); vec.push(0);
...@@ -223,7 +234,7 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro ...@@ -223,7 +234,7 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro
Some(buf) => { Some(buf) => {
let mut buf = MaybeAllocated::Borrowed(buf); let mut buf = MaybeAllocated::Borrowed(buf);
if buf.len() < buf.len() { if buf.len() < strings.len() {
platform::ERRNO.set(errno::ERANGE); platform::ERRNO.set(errno::ERANGE);
return Err(Error::BufTooSmall); return Err(Error::BufTooSmall);
} }
...@@ -299,20 +310,38 @@ pub unsafe extern "C" fn getgrgid_r( ...@@ -299,20 +310,38 @@ pub unsafe extern "C" fn getgrgid_r(
buflen: usize, buflen: usize,
result: *mut *mut group, result: *mut *mut group,
) -> c_int { ) -> c_int {
// In case of error or the requested entry is not found.
*result = ptr::null_mut();
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else { let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
return ENOENT; return ENOENT;
}; };
for line in BufReader::new(db).lines() { for line in BufReader::new(db).lines() {
let Ok(line) = line else { return EINVAL }; let Ok(line) = line else { return EINVAL };
let Ok(mut grp) = parse_grp( let grp = match parse_grp(
line, line,
Some(DestBuffer { Some(DestBuffer {
ptr: buffer as *mut u8, ptr: buffer as *mut u8,
len: buflen, len: buflen,
}), }),
) else { ) {
return EINVAL; Ok(grp) => grp,
Err(err) => {
return match err {
Error::BufTooSmall => ERANGE,
Error::EOF
| Error::SyntaxError
| Error::FromUtf8Error(_)
| Error::ParseIntError(_)
| Error::Other => EINVAL,
Error::Misc(io_err) => match io_err.kind() {
io::ErrorKind::InvalidData | io::ErrorKind::UnexpectedEof => EINVAL,
io::ErrorKind::NotFound => ENOENT,
_ => EIO,
},
}
}
}; };
if grp.reference.gr_gid == gid { if grp.reference.gr_gid == gid {
...@@ -323,7 +352,8 @@ pub unsafe extern "C" fn getgrgid_r( ...@@ -323,7 +352,8 @@ pub unsafe extern "C" fn getgrgid_r(
} }
} }
return ENOENT; // The requested entry was not found.
return 0;
} }
// MT-Safe locale // MT-Safe locale
......
...@@ -45,7 +45,15 @@ impl Rwlock { ...@@ -45,7 +45,15 @@ impl Rwlock {
}; };
waiting_wr = expected & WAITING_WR; waiting_wr = expected & WAITING_WR;
let _ = crate::sync::futex_wait(&self.state, expected, deadline); if actual & COUNT_MASK > 0 {
let _ = crate::sync::futex_wait(&self.state, expected, deadline);
} else {
// We must avoid blocking indefinitely in our `futex_wait()`, in this case
// where it's possible that `self.state == expected` but our futex might
// never be woken again, because it's possible that all other threads
// already did their `futex_wake()` before we would've done our
// `futex_wait()`.
}
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment