Skip to content

Commit

Permalink
Fix fd_seek underflow
Browse files Browse the repository at this point in the history
This commit adds a checked subtraction to `fd_seek` so that passing in a
large negative offset does not underflow.

fixes #4589
  • Loading branch information
yagehu committed Apr 22, 2024
1 parent f5b182f commit e3e4965
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/wasix/src/syscalls/wasi/fd_seek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,12 @@ pub(crate) fn fd_seek_internal(
fd_entry.offset.fetch_add(offset, Ordering::AcqRel) + offset
} else if offset < 0 {
let offset = offset.unsigned_abs();
// FIXME: need to handle underflow!
fd_entry.offset.fetch_sub(offset, Ordering::AcqRel) - offset

wasi_try_ok_ok!(fd_entry
.offset
.fetch_sub(offset, Ordering::AcqRel)
.checked_sub(offset)
.ok_or(Errno::Inval))
} else {
fd_entry.offset.load(Ordering::Acquire)
}
Expand Down
32 changes: 32 additions & 0 deletions tests/wasi-fyi/fd_seek_cur_negative_underflow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::os::fd::AsRawFd;

#[link(wasm_import_module = "wasi_snapshot_preview1")]
extern "C" {
pub fn fd_seek(fd: i32, offset: i64, whence: i32, filesize: i32) -> i32;
}

const ERRNO_INVAL: i32 = 28;

const WHENCE_CUR: i32 = 1;

fn main() {
unsafe {
let large_negative_offset = -6551085931117533355;
let mut filesize = 0u64;

let f = std::fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("test.sh")
.unwrap();
let errno = fd_seek(
f.as_raw_fd(),
large_negative_offset,
WHENCE_CUR,
&mut filesize as *mut u64 as usize as i32,
);

assert_eq!(errno, ERRNO_INVAL);
}
}

0 comments on commit e3e4965

Please sign in to comment.