From 802748b611cbc86d29d767e5197f5a76e1803bc8 Mon Sep 17 00:00:00 2001 From: Derick Eddington <124489-kcired@users.noreply.gitlab.redox-os.org> Date: Sat, 6 Jul 2024 01:13:23 -0700 Subject: [PATCH 1/3] Fix `Rwlock::acquire_write_lock` to avoid blocking indefinitely. Without this fix, `tests/bins_static/pthread/rwlock_randtest` would sometimes get stuck blocking forever with only 1+ threads all doing `pthread_rwlock_wrlock()` but all the other threads having finished. --- src/sync/rwlock.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sync/rwlock.rs b/src/sync/rwlock.rs index f5ecaf12fe..b787a8e857 100644 --- a/src/sync/rwlock.rs +++ b/src/sync/rwlock.rs @@ -45,7 +45,15 @@ impl Rwlock { }; 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()`. + } } } } From 7c81de68b8e13b92cecc5f58ec5dbf759e42f4a9 Mon Sep 17 00:00:00 2001 From: Derick Eddington <124489-kcired@users.noreply.gitlab.redox-os.org> Date: Sat, 6 Jul 2024 16:52:47 -0700 Subject: [PATCH 2/3] Fix `header::grp::parse_grp`. --- src/header/grp/mod.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/header/grp/mod.rs b/src/header/grp/mod.rs index 4958791cd9..a91d7e4de7 100644 --- a/src/header/grp/mod.rs +++ b/src/header/grp/mod.rs @@ -187,8 +187,8 @@ fn parse_grp(line: String, destbuf: Option) -> Result) -> Result) -> Result(); + 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 - unsafe { - *member_array_ptr.add(i) = vec.len(); - } + member_ptr.copy_from_slice(&cur_offset.to_ne_bytes()); vec.extend(member); vec.push(0); @@ -223,7 +234,7 @@ fn parse_grp(line: String, destbuf: Option) -> Result { let mut buf = MaybeAllocated::Borrowed(buf); - if buf.len() < buf.len() { + if buf.len() < strings.len() { platform::ERRNO.set(errno::ERANGE); return Err(Error::BufTooSmall); } From 572f211be0eb41aa1e7a2cda5848ff0bedc6832c Mon Sep 17 00:00:00 2001 From: Derick Eddington <124489-kcired@users.noreply.gitlab.redox-os.org> Date: Sat, 6 Jul 2024 18:25:00 -0700 Subject: [PATCH 3/3] Fix `getgrgid_r`. --- src/header/grp/mod.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/header/grp/mod.rs b/src/header/grp/mod.rs index a91d7e4de7..700db8df74 100644 --- a/src/header/grp/mod.rs +++ b/src/header/grp/mod.rs @@ -310,20 +310,38 @@ pub unsafe extern "C" fn getgrgid_r( buflen: usize, result: *mut *mut group, ) -> 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 { return ENOENT; }; for line in BufReader::new(db).lines() { let Ok(line) = line else { return EINVAL }; - let Ok(mut grp) = parse_grp( + let grp = match parse_grp( line, Some(DestBuffer { ptr: buffer as *mut u8, 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 { @@ -334,7 +352,8 @@ pub unsafe extern "C" fn getgrgid_r( } } - return ENOENT; + // The requested entry was not found. + return 0; } // MT-Safe locale