fix(std/wasi): disallow path_open outside of pre-opened dirfd (#8078)

This commit is contained in:
Casper Beyer 2020-10-24 22:04:59 +08:00 committed by GitHub
parent 35f184cdcc
commit 2a83b22385
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 7 deletions

View file

@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { resolve } from "../path/mod.ts";
import { relative, resolve } from "../path/mod.ts";
const CLOCKID_REALTIME = 0;
const CLOCKID_MONOTONIC = 1;
@ -83,7 +83,7 @@ const _ERRNO_STALE = 72;
const ERRNO_TIMEDOUT = 73;
const _ERRNO_TXTBSY = 74;
const _ERRNO_XDEV = 75;
const _ERRNO_NOTCAPABLE = 76;
const ERRNO_NOTCAPABLE = 76;
const RIGHTS_FD_DATASYNC = 0x0000000000000001n;
const RIGHTS_FD_READ = 0x0000000000000002n;
@ -1201,9 +1201,35 @@ export default class Context {
return ERRNO_INVAL;
}
const text = new TextDecoder();
const data = new Uint8Array(this.memory.buffer, pathOffset, pathLength);
const path = resolve(entry.path!, text.decode(data));
const textDecoder = new TextDecoder();
const pathData = new Uint8Array(
this.memory.buffer,
pathOffset,
pathLength,
);
const resolvedPath = resolve(entry.path!, textDecoder.decode(pathData));
if (relative(entry.path, resolvedPath).startsWith("..")) {
return ERRNO_NOTCAPABLE;
}
let path;
if (
(dirflags & LOOKUPFLAGS_SYMLINK_FOLLOW) == LOOKUPFLAGS_SYMLINK_FOLLOW
) {
try {
path = Deno.realPathSync(resolvedPath);
console.log("RESOLVED REAL PATH: %s", path);
if (relative(entry.path, path).startsWith("..")) {
return ERRNO_NOTCAPABLE;
}
} catch (_err) {
path = resolvedPath;
}
} else {
path = resolvedPath;
}
if ((oflags & OFLAGS_DIRECTORY) !== 0) {
// XXX (caspervonb) this isn't ideal as we can't get a rid for the

View file

@ -35,6 +35,7 @@ const tests = [
"testdata/wasi_fd_write_file.wasm",
"testdata/wasi_fd_write_stderr.wasm",
"testdata/wasi_fd_write_stdout.wasm",
"testdata/wasi_path_open.wasm",
"testdata/wasi_proc_exit.wasm",
"testdata/wasi_random_get.wasm",
"testdata/wasi_sched_yield.wasm",
@ -46,9 +47,13 @@ const ignore = [
// TODO(caspervonb) investigate why these tests are failing on windows and fix
// them.
// The failing tests all involve symlinks in some way, my best guess so far is
// that there's something going wrong with copying the symlinks over to the
// temporary working directory, but only in some cases.
if (Deno.build.os == "windows") {
ignore.push("testdata/std_fs_metadata.wasm");
ignore.push("testdata/std_fs_read_dir.wasm");
ignore.push("testdata/wasi_path_open.wasm");
}
const rootdir = path.dirname(path.fromFileUrl(import.meta.url));
@ -64,7 +69,14 @@ for (const pathname of tests) {
);
const options = JSON.parse(prelude);
const workdir = await Deno.makeTempDir();
// TODO(caspervonb) investigate more.
// On Windows creating a tempdir in the default directory breaks nearly
// all the tests, possibly due to symlinks pointing to the original file
// which crosses drive boundaries.
const workdir = await Deno.makeTempDir({
dir: testdir,
});
await copy(
path.join(testdir, "fixtures"),
path.join(workdir, "fixtures"),

@ -1 +1 @@
Subproject commit ffbe85d2315ae0104534f38037903de38b6f2e63
Subproject commit 324366afb925a3974c6135390c280aff9c4e0e99