Skip to content

Commit aec935f

Browse files
authored
fix(wasip1): fd_renumber panic in the adapter (#11277)
* Revert "test(wasip1): ignore `fd_renumber` tests when using adapter" This reverts commit 00325ff36d44a3cf666085d56a7c80e907636d8b. * fix(wasip1-adapter): prevent `unreachable` panic on `fd_renumber` Signed-off-by: Roman Volosatovs <[email protected]> * doc: document adapter panic fix Signed-off-by: Roman Volosatovs <[email protected]> * doc: add PR reference prtest:full Signed-off-by: Roman Volosatovs <[email protected]> --------- Signed-off-by: Roman Volosatovs <[email protected]>
1 parent 0c93530 commit aec935f

File tree

5 files changed

+29
-16
lines changed

5 files changed

+29
-16
lines changed

RELEASES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Unreleased.
1111
* Fix a panic in the host caused by preview1 guests using `fd_renumber`.
1212
[CVE-2025-53901](https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-fm79-3f68-h2fc).
1313

14+
* Fix a panic in the preview1 adapter caused by guests using `fd_renumber`.
15+
[#11277](https://github.com/bytecodealliance/wasmtime/pull/11277)
16+
1417
--------------------------------------------------------------------------------
1518

1619
Release notes for previous releases of Wasmtime can be found on the respective

crates/test-programs/src/bin/preview1_renumber.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,15 @@ unsafe fn test_renumber(dir_fd: wasip1::Fd) {
9191
"file descriptor range check",
9292
);
9393

94-
wasip1::fd_renumber(fd_file3, u32::MAX).expect("renumbering file FD to `u32::MAX`");
94+
wasip1::fd_renumber(fd_file3, 127).expect("renumbering FD to 127");
95+
match wasip1::fd_renumber(127, u32::MAX) {
96+
Err(wasip1::ERRNO_NOMEM) => {
97+
// The preview1 adapter cannot handle more than 128 descriptors
98+
eprintln!("fd_renumber({fd_file3}, {}) returned NOMEM", u32::MAX)
99+
}
100+
res => res.expect("renumbering FD to `u32::MAX`"),
101+
}
102+
95103
let fd_file4 = wasip1::path_open(
96104
dir_fd,
97105
0,

crates/wasi-preview1-component-adapter/src/descriptors.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ impl Descriptors {
330330
.ok_or(wasi::ERRNO_BADF)
331331
}
332332

333-
// Internal: close a fd, returning the descriptor.
334-
fn close_(&mut self, fd: Fd) -> Result<Descriptor, Errno> {
333+
// Close an fd.
334+
pub fn close(&mut self, fd: Fd) -> Result<(), Errno> {
335335
// Throw an error if closing an fd which is already closed
336336
match self.get(fd)? {
337337
Descriptor::Closed(_) => Err(wasi::ERRNO_BADF)?,
@@ -341,12 +341,7 @@ impl Descriptors {
341341
let last_closed = self.closed;
342342
let prev = std::mem::replace(self.get_mut(fd)?, Descriptor::Closed(last_closed));
343343
self.closed = Some(fd);
344-
Ok(prev)
345-
}
346-
347-
// Close an fd.
348-
pub fn close(&mut self, fd: Fd) -> Result<(), Errno> {
349-
drop(self.close_(fd)?);
344+
drop(prev);
350345
Ok(())
351346
}
352347

@@ -366,11 +361,20 @@ impl Descriptors {
366361
while self.table_len.get() as u32 <= to_fd {
367362
self.push_closed()?;
368363
}
369-
// Then, close from_fd and put its contents into to_fd:
370-
let desc = self.close_(from_fd)?;
371-
// TODO FIXME if this overwrites a preopen, do we need to clear it from the preopen table?
372-
*self.get_mut(to_fd)? = desc;
373-
364+
// Throw an error if renumbering a closed fd
365+
match self.get(from_fd)? {
366+
Descriptor::Closed(_) => Err(wasi::ERRNO_BADF)?,
367+
_ => {}
368+
}
369+
// Close from_fd and put its contents into to_fd
370+
if from_fd != to_fd {
371+
// Mutate the descriptor to be closed, and push the closed fd onto the head of the linked list:
372+
let last_closed = self.closed;
373+
let desc = std::mem::replace(self.get_mut(from_fd)?, Descriptor::Closed(last_closed));
374+
self.closed = Some(from_fd);
375+
// TODO FIXME if this overwrites a preopen, do we need to clear it from the preopen table?
376+
*self.get_mut(to_fd)? = desc;
377+
}
374378
Ok(())
375379
}
376380

crates/wasi/tests/all/p2/async_.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ async fn preview1_remove_nonempty_directory() {
231231
.await
232232
.unwrap()
233233
}
234-
#[ignore = "panics"]
235234
#[test_log::test(tokio::test(flavor = "multi_thread"))]
236235
async fn preview1_renumber() {
237236
run(PREVIEW1_RENUMBER_COMPONENT, false).await.unwrap()

crates/wasi/tests/all/p2/sync.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ fn preview1_remove_directory() {
187187
fn preview1_remove_nonempty_directory() {
188188
run(PREVIEW1_REMOVE_NONEMPTY_DIRECTORY_COMPONENT, false).unwrap()
189189
}
190-
#[ignore = "panics"]
191190
#[test_log::test]
192191
fn preview1_renumber() {
193192
run(PREVIEW1_RENUMBER_COMPONENT, false).unwrap()

0 commit comments

Comments
 (0)