mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
feat(unstable): allow specifing gid and uid for subprocess (#11586)
This commit is contained in:
parent
274ff6c469
commit
a655a0f3e4
5 changed files with 90 additions and 0 deletions
6
cli/dts/lib.deno.ns.d.ts
vendored
6
cli/dts/lib.deno.ns.d.ts
vendored
|
@ -2034,6 +2034,12 @@ declare namespace Deno {
|
||||||
* Environmental variables for subprocess can be specified using `opt.env`
|
* Environmental variables for subprocess can be specified using `opt.env`
|
||||||
* mapping.
|
* mapping.
|
||||||
*
|
*
|
||||||
|
* `opt.uid` sets the child process’s user ID. This translates to a setuid call
|
||||||
|
* in the child process. Failure in the setuid call will cause the spawn to fail.
|
||||||
|
*
|
||||||
|
* `opt.gid` is similar to `opt.uid`, but sets the group ID of the child process.
|
||||||
|
* This has the same semantics as the uid field.
|
||||||
|
*
|
||||||
* By default subprocess inherits stdio of parent process. To change that
|
* By default subprocess inherits stdio of parent process. To change that
|
||||||
* `opt.stdout`, `opt.stderr` and `opt.stdin` can be specified independently -
|
* `opt.stdout`, `opt.stderr` and `opt.stdin` can be specified independently -
|
||||||
* they can be set to either an rid of open file or set to "inherit" "piped"
|
* they can be set to either an rid of open file or set to "inherit" "piped"
|
||||||
|
|
4
cli/dts/lib.deno.unstable.d.ts
vendored
4
cli/dts/lib.deno.unstable.d.ts
vendored
|
@ -713,8 +713,12 @@ declare namespace Deno {
|
||||||
export function run<
|
export function run<
|
||||||
T extends RunOptions & {
|
T extends RunOptions & {
|
||||||
clearEnv?: boolean;
|
clearEnv?: boolean;
|
||||||
|
gid?: number;
|
||||||
|
uid?: number;
|
||||||
} = RunOptions & {
|
} = RunOptions & {
|
||||||
clearEnv?: boolean;
|
clearEnv?: boolean;
|
||||||
|
gid?: number;
|
||||||
|
uid?: number;
|
||||||
},
|
},
|
||||||
>(opt: T): Process<T>;
|
>(opt: T): Process<T>;
|
||||||
|
|
||||||
|
|
|
@ -537,3 +537,59 @@ unitTest(
|
||||||
p.close();
|
p.close();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
unitTest(
|
||||||
|
{ perms: { run: true, read: true }, ignore: Deno.build.os === "windows" },
|
||||||
|
async function uid(): Promise<void> {
|
||||||
|
const p = Deno.run({
|
||||||
|
cmd: [
|
||||||
|
"id",
|
||||||
|
"-u",
|
||||||
|
],
|
||||||
|
stdout: "piped",
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentUid = new TextDecoder().decode(await p.output());
|
||||||
|
p.close();
|
||||||
|
|
||||||
|
if (currentUid !== "0") {
|
||||||
|
assertThrows(() => {
|
||||||
|
Deno.run({
|
||||||
|
cmd: [
|
||||||
|
"echo",
|
||||||
|
"fhqwhgads",
|
||||||
|
],
|
||||||
|
uid: 0,
|
||||||
|
});
|
||||||
|
}, Deno.errors.PermissionDenied);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
unitTest(
|
||||||
|
{ perms: { run: true, read: true }, ignore: Deno.build.os === "windows" },
|
||||||
|
async function gid(): Promise<void> {
|
||||||
|
const p = Deno.run({
|
||||||
|
cmd: [
|
||||||
|
"id",
|
||||||
|
"-g",
|
||||||
|
],
|
||||||
|
stdout: "piped",
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentGid = new TextDecoder().decode(await p.output());
|
||||||
|
p.close();
|
||||||
|
|
||||||
|
if (currentGid !== "0") {
|
||||||
|
assertThrows(() => {
|
||||||
|
Deno.run({
|
||||||
|
cmd: [
|
||||||
|
"echo",
|
||||||
|
"fhqwhgads",
|
||||||
|
],
|
||||||
|
gid: 0,
|
||||||
|
});
|
||||||
|
}, Deno.errors.PermissionDenied);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -102,6 +102,8 @@
|
||||||
cwd = undefined,
|
cwd = undefined,
|
||||||
clearEnv = false,
|
clearEnv = false,
|
||||||
env = {},
|
env = {},
|
||||||
|
gid = undefined,
|
||||||
|
uid = undefined,
|
||||||
stdout = "inherit",
|
stdout = "inherit",
|
||||||
stderr = "inherit",
|
stderr = "inherit",
|
||||||
stdin = "inherit",
|
stdin = "inherit",
|
||||||
|
@ -114,6 +116,8 @@
|
||||||
cwd,
|
cwd,
|
||||||
clearEnv,
|
clearEnv,
|
||||||
env: ObjectEntries(env),
|
env: ObjectEntries(env),
|
||||||
|
gid,
|
||||||
|
uid,
|
||||||
stdin: isRid(stdin) ? "" : stdin,
|
stdin: isRid(stdin) ? "" : stdin,
|
||||||
stdout: isRid(stdout) ? "" : stdout,
|
stdout: isRid(stdout) ? "" : stdout,
|
||||||
stderr: isRid(stderr) ? "" : stderr,
|
stderr: isRid(stderr) ? "" : stderr,
|
||||||
|
|
|
@ -63,6 +63,8 @@ pub struct RunArgs {
|
||||||
cwd: Option<String>,
|
cwd: Option<String>,
|
||||||
clear_env: bool,
|
clear_env: bool,
|
||||||
env: Vec<(String, String)>,
|
env: Vec<(String, String)>,
|
||||||
|
gid: Option<u32>,
|
||||||
|
uid: Option<u32>,
|
||||||
stdin: String,
|
stdin: String,
|
||||||
stdout: String,
|
stdout: String,
|
||||||
stderr: String,
|
stderr: String,
|
||||||
|
@ -123,6 +125,24 @@ fn op_run(
|
||||||
c.env(key, value);
|
c.env(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
if let Some(gid) = run_args.gid {
|
||||||
|
super::check_unstable(state, "Deno.run.gid");
|
||||||
|
c.gid(gid);
|
||||||
|
}
|
||||||
|
#[cfg(unix)]
|
||||||
|
if let Some(uid) = run_args.uid {
|
||||||
|
super::check_unstable(state, "Deno.run.uid");
|
||||||
|
c.uid(uid);
|
||||||
|
}
|
||||||
|
#[cfg(unix)]
|
||||||
|
unsafe {
|
||||||
|
c.pre_exec(|| {
|
||||||
|
libc::setgroups(0, std::ptr::null());
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: make this work with other resources, eg. sockets
|
// TODO: make this work with other resources, eg. sockets
|
||||||
if !run_args.stdin.is_empty() {
|
if !run_args.stdin.is_empty() {
|
||||||
c.stdin(subprocess_stdio_map(run_args.stdin.as_ref())?);
|
c.stdin(subprocess_stdio_map(run_args.stdin.as_ref())?);
|
||||||
|
|
Loading…
Reference in a new issue