summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/permissions/lib.rs46
-rw-r--r--tests/unit/os_test.ts44
-rw-r--r--tests/unit/read_file_test.ts2
-rw-r--r--tests/unit/read_text_file_test.ts2
4 files changed, 59 insertions, 35 deletions
diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs
index 0d9d37a36..b0fa9eb10 100644
--- a/runtime/permissions/lib.rs
+++ b/runtime/permissions/lib.rs
@@ -2241,7 +2241,50 @@ pub fn create_child_permissions(
main_perms: &mut Permissions,
child_permissions_arg: ChildPermissionsArg,
) -> Result<Permissions, AnyError> {
+ fn is_granted_unary(arg: &ChildUnaryPermissionArg) -> bool {
+ match arg {
+ ChildUnaryPermissionArg::Inherit | ChildUnaryPermissionArg::Granted => {
+ true
+ }
+ ChildUnaryPermissionArg::NotGranted
+ | ChildUnaryPermissionArg::GrantedList(_) => false,
+ }
+ }
+
+ fn is_granted_unit(arg: &ChildUnitPermissionArg) -> bool {
+ match arg {
+ ChildUnitPermissionArg::Inherit | ChildUnitPermissionArg::Granted => true,
+ ChildUnitPermissionArg::NotGranted => false,
+ }
+ }
+
let mut worker_perms = Permissions::none_without_prompt();
+
+ worker_perms.all = main_perms
+ .all
+ .create_child_permissions(ChildUnitPermissionArg::Inherit)?;
+
+ // downgrade the `worker_perms.all` based on the other values
+ if worker_perms.all.query() == PermissionState::Granted {
+ let unary_perms = [
+ &child_permissions_arg.read,
+ &child_permissions_arg.write,
+ &child_permissions_arg.net,
+ &child_permissions_arg.env,
+ &child_permissions_arg.sys,
+ &child_permissions_arg.run,
+ &child_permissions_arg.ffi,
+ ];
+ let unit_perms = [&child_permissions_arg.hrtime];
+ let allow_all = unary_perms.into_iter().all(is_granted_unary)
+ && unit_perms.into_iter().all(is_granted_unit);
+ if !allow_all {
+ worker_perms.all.revoke();
+ }
+ }
+
+ // WARNING: When adding a permission here, ensure it is handled
+ // in the worker_perms.all block above
worker_perms.read = main_perms
.read
.create_child_permissions(child_permissions_arg.read)?;
@@ -2266,9 +2309,6 @@ pub fn create_child_permissions(
worker_perms.hrtime = main_perms
.hrtime
.create_child_permissions(child_permissions_arg.hrtime)?;
- worker_perms.all = main_perms
- .all
- .create_child_permissions(ChildUnitPermissionArg::Inherit)?;
Ok(worker_perms)
}
diff --git a/tests/unit/os_test.ts b/tests/unit/os_test.ts
index 80b421e63..42b598511 100644
--- a/tests/unit/os_test.ts
+++ b/tests/unit/os_test.ts
@@ -3,7 +3,6 @@ import {
assert,
assertEquals,
assertNotEquals,
- assertStringIncludes,
assertThrows,
} from "./test_util.ts";
@@ -197,36 +196,21 @@ Deno.test({ permissions: { read: false } }, function execPathPerm() {
);
});
-Deno.test(async function execPathPerm() {
- if (Deno.build.os !== "linux") return;
- // This is hack to bypass a bug in deno test runner,
- // Currently if you specify {read: true} permission, it will stil pass --allow-all (tests are run with deno test --allow-all) implicitly, so this test won't work
- // The workaround is to spawn a deno executable with the needed permissions
- // TODO(#25085): remove this hack when the bug is fixed
- const cmd = new Deno.Command(Deno.execPath(), {
- args: ["run", "--allow-read", "-"],
- stdin: "piped",
- stderr: "piped",
- }).spawn();
- const stdinWriter = cmd.stdin.getWriter();
- await stdinWriter
- .write(
- new TextEncoder().encode('Deno.readTextFileSync("/proc/net/dev")'),
+Deno.test(
+ {
+ ignore: Deno.build.os !== "linux",
+ permissions: { read: true, run: false },
+ },
+ function procRequiresAllowAll() {
+ assertThrows(
+ () => {
+ Deno.readTextFileSync("/proc/net/dev");
+ },
+ Deno.errors.PermissionDenied,
+ `Requires all access to "/proc/net/dev", run again with the --allow-all flag`,
);
- await stdinWriter.close();
- await cmd.status;
-
- const stderrReder = cmd.stderr.getReader();
- const error = await stderrReder
- .read()
- .then((r) => new TextDecoder().decode(r.value));
- await stderrReder.cancel();
-
- assertStringIncludes(
- error,
- `PermissionDenied: Requires all access to "/proc/net/dev", run again with the --allow-all flag`,
- );
-});
+ },
+);
Deno.test(
{ permissions: { sys: ["loadavg"] } },
diff --git a/tests/unit/read_file_test.ts b/tests/unit/read_file_test.ts
index 562bf9969..67944813b 100644
--- a/tests/unit/read_file_test.ts
+++ b/tests/unit/read_file_test.ts
@@ -148,7 +148,7 @@ Deno.test(
);
Deno.test(
- { permissions: { read: true }, ignore: Deno.build.os !== "linux" },
+ { ignore: Deno.build.os !== "linux" },
async function readFileProcFs() {
const data = await Deno.readFile("/proc/self/stat");
assert(data.byteLength > 0);
diff --git a/tests/unit/read_text_file_test.ts b/tests/unit/read_text_file_test.ts
index 94aa5f0a8..cab75fd47 100644
--- a/tests/unit/read_text_file_test.ts
+++ b/tests/unit/read_text_file_test.ts
@@ -146,7 +146,7 @@ Deno.test(
);
Deno.test(
- { permissions: { read: true }, ignore: Deno.build.os !== "linux" },
+ { ignore: Deno.build.os !== "linux" },
async function readTextFileProcFs() {
const data = await Deno.readTextFile("/proc/self/stat");
assert(data.length > 0);