Skip to content

Commit

Permalink
protect preopened inodes from being closed (#5275)
Browse files Browse the repository at this point in the history
  • Loading branch information
maminrayej authored Nov 29, 2024
2 parents a6398b3 + f0cff25 commit 6c26e4e
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ jobs:
uses: dtolnay/rust-toolchain@stable
with:
toolchain: nightly
targets: "wasm32-wasi"
targets: "wasm32-wasip1"
- name: Install wasm-pack
run: |
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
Expand Down
12 changes: 10 additions & 2 deletions lib/wasix/src/syscalls/wasi/fd_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ use crate::syscalls::*;
pub fn fd_close(mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd) -> Result<Errno, WasiError> {
wasi_try_ok!(WasiEnv::process_signals_and_exit(&mut ctx)?);

let env = ctx.data();
let (_, mut state) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };

if let Ok(pfd) = state.fs.get_fd(fd) {
if pfd.inode.is_preopened {
trace!("Skipping fd_close({})", fd);
return Ok(Errno::Success);
}
}

// HACK: As a special case, we don't want to close fd 3 because it can break
// some programs...
// - On Wasix, we have some default fd, 0:stdin, 1:stdout, 2:stderr, 3:root
Expand All @@ -28,8 +38,6 @@ pub fn fd_close(mut ctx: FunctionEnvMut<'_, WasiEnv>, fd: WasiFd) -> Result<Errn
return Ok(Errno::Success);
}

let env = ctx.data();
let (_, mut state) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };
wasi_try_ok!(state.fs.close_fd(fd));

#[cfg(feature = "journal")]
Expand Down
2 changes: 1 addition & 1 deletion tests/wasi-fyi/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ for input in *.rs; do
output="$(basename $input .rs).wasm"

echo "Compiling $input"
rustc +nightly --target=wasm32-wasi -o "$output" "$input"
rustc +nightly --target=wasm32-wasip1 -o "$output" "$input"
done
2 changes: 1 addition & 1 deletion tests/wasi-fyi/ported_close_preopen_fd.stdout
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
accessing preopen fd was a success
Closing preopen fd was a success
accessing closed preopen fd was an EBADF error: true
accessing closed preopen fd was an EBADF error: false
1 change: 1 addition & 0 deletions tests/wasi-fyi/ported_fd_close.stdout
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Successfully closed file!
Successfully closed stderr!
Successfully closed stdin!
Successfully closed stdout!
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
(wasi_test "close_preopen_fd.wasm"
(map_dirs "hamlet:test_fs/hamlet")
(assert_return (i64.const 0))
(assert_stdout "accessing preopen fd was a success\nClosing preopen fd was a success\naccessing closed preopen fd was an EBADF error: true\n")
(assert_stdout "accessing preopen fd was a success\nClosing preopen fd was a success\naccessing closed preopen fd was an EBADF error: false\n")
)
2 changes: 1 addition & 1 deletion tests/wasi-wast/wasi/snapshot1/close_preopen_fd.wast
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
(wasi_test "close_preopen_fd.wasm"
(map_dirs "hamlet:test_fs/hamlet")
(assert_return (i64.const 0))
(assert_stdout "accessing preopen fd was a success\nClosing preopen fd was a success\naccessing closed preopen fd was an EBADF error: true\n")
(assert_stdout "accessing preopen fd was a success\nClosing preopen fd was a success\naccessing closed preopen fd was an EBADF error: false\n")
)
2 changes: 1 addition & 1 deletion tests/wasi-wast/wasi/unstable/close_preopen_fd.wast
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
(wasi_test "close_preopen_fd.wasm"
(map_dirs "hamlet:test_fs/hamlet")
(assert_return (i64.const 0))
(assert_stdout "accessing preopen fd was a success\nClosing preopen fd was a success\naccessing closed preopen fd was an EBADF error: true\n")
(assert_stdout "accessing preopen fd was a success\nClosing preopen fd was a success\naccessing closed preopen fd was an EBADF error: false\n")
)
49 changes: 49 additions & 0 deletions tests/wasix/closing-pre-opened-dirs/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>

int main() {
const char *expected_entries[] = {".", "..", "main.c", "main.wasm", "output", "run.sh", NULL};

for (int fd = 0; fd <= 5; fd++) {
close(fd);
}

DIR *dir = opendir(".");
if (!dir) {
printf("opendir");
exit(EXIT_FAILURE);
}

struct dirent *entry;
int i = 0;
while ((entry = readdir(dir)) != NULL) {
if (expected_entries[i] == NULL) {
fprintf(stdout, "Unexpected extra entry: %s\n", entry->d_name);
closedir(dir);
exit(EXIT_FAILURE);
}

int cmp_result = strcmp(entry->d_name, expected_entries[i]);
if (cmp_result != 0) {
printf("1");
return 1;
}

i++;
}

if (expected_entries[i] != NULL) {
printf("1");
return 1;
}

closedir(dir);

printf("0");
return 0;
}

5 changes: 5 additions & 0 deletions tests/wasix/closing-pre-opened-dirs/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
rm output

$WASMER -q run main.wasm --dir . > output

printf "0" | diff -u output - 1>/dev/null

0 comments on commit 6c26e4e

Please sign in to comment.