Skip to content

Commit e6d14b8

Browse files
Overflow fixes - Cap timespec conversions to prevent EINVAL with huge timeouts
1 parent 2903644 commit e6d14b8

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

src/uu/timeout/src/timeout.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,9 @@ fn send_signal(process: &mut Child, signal: usize, foreground: bool) {
230230
/// * `Ok(Some(signal))` - A signal was received
231231
/// * `Ok(None)` - Timeout expired
232232
/// * `Err(e)` - An error occurred
233-
#[cfg(not(target_os = "macos"))]
233+
#[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
234234
fn wait_for_signal(signals: &[Signal], until: Option<Instant>) -> io::Result<Option<Signal>> {
235-
// Linux/FreeBSD: Use sigtimedwait() for efficient signal waiting
235+
// Linux: Use sigtimedwait() for efficient signal waiting
236236
// Create signal set from the provided signals
237237
let mut sigset = SigSet::empty();
238238
for &sig in signals {
@@ -255,8 +255,10 @@ fn wait_for_signal(signals: &[Signal], until: Option<Instant>) -> io::Result<Opt
255255
tv_nsec: 0,
256256
}
257257
} else {
258+
// Cap timeout to avoid overflow in timespec conversion
259+
let timeout_secs = timeout.as_secs().min(libc::time_t::MAX as u64);
258260
libc::timespec {
259-
tv_sec: timeout.as_secs() as libc::time_t,
261+
tv_sec: timeout_secs as libc::time_t,
260262
tv_nsec: timeout.subsec_nanos() as libc::c_long,
261263
}
262264
};
@@ -311,8 +313,10 @@ fn wait_for_signal(signals: &[Signal], until: Option<Instant>) -> io::Result<Opt
311313
// Calculate timeout
312314
let timeout = if let Some(deadline) = until {
313315
let remaining = deadline.saturating_duration_since(Instant::now());
316+
// Cap timeout to avoid overflow in timespec conversion
317+
let timeout_secs = remaining.as_secs().min(libc::time_t::MAX as u64);
314318
Some(libc::timespec {
315-
tv_sec: remaining.as_secs() as libc::time_t,
319+
tv_sec: timeout_secs as libc::time_t,
316320
tv_nsec: remaining.subsec_nanos() as libc::c_long,
317321
})
318322
} else {

src/uucore/src/lib/features/process.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,10 @@ impl ChildExt for Child {
259259
// Calculate timeout and deadline
260260
// Use checked_add to prevent overflow with very large timeouts
261261
let deadline = Instant::now().checked_add(timeout);
262+
// Cap timeout to avoid overflow in timespec conversion
263+
let timeout_secs = timeout.as_secs().min(libc::time_t::MAX as u64);
262264
let timeout_spec = Some(libc::timespec {
263-
tv_sec: timeout.as_secs() as libc::time_t,
265+
tv_sec: timeout_secs as libc::time_t,
264266
tv_nsec: timeout.subsec_nanos() as libc::c_long,
265267
});
266268

0 commit comments

Comments
 (0)