mirror of
https://github.com/denoland/deno.git
synced 2024-12-21 23:04:45 -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`
|
||||
* 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
|
||||
* `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"
|
||||
|
|
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<
|
||||
T extends RunOptions & {
|
||||
clearEnv?: boolean;
|
||||
gid?: number;
|
||||
uid?: number;
|
||||
} = RunOptions & {
|
||||
clearEnv?: boolean;
|
||||
gid?: number;
|
||||
uid?: number;
|
||||
},
|
||||
>(opt: T): Process<T>;
|
||||
|
||||
|
|
|
@ -537,3 +537,59 @@ unitTest(
|
|||
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,
|
||||
clearEnv = false,
|
||||
env = {},
|
||||
gid = undefined,
|
||||
uid = undefined,
|
||||
stdout = "inherit",
|
||||
stderr = "inherit",
|
||||
stdin = "inherit",
|
||||
|
@ -114,6 +116,8 @@
|
|||
cwd,
|
||||
clearEnv,
|
||||
env: ObjectEntries(env),
|
||||
gid,
|
||||
uid,
|
||||
stdin: isRid(stdin) ? "" : stdin,
|
||||
stdout: isRid(stdout) ? "" : stdout,
|
||||
stderr: isRid(stderr) ? "" : stderr,
|
||||
|
|
|
@ -63,6 +63,8 @@ pub struct RunArgs {
|
|||
cwd: Option<String>,
|
||||
clear_env: bool,
|
||||
env: Vec<(String, String)>,
|
||||
gid: Option<u32>,
|
||||
uid: Option<u32>,
|
||||
stdin: String,
|
||||
stdout: String,
|
||||
stderr: String,
|
||||
|
@ -123,6 +125,24 @@ fn op_run(
|
|||
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
|
||||
if !run_args.stdin.is_empty() {
|
||||
c.stdin(subprocess_stdio_map(run_args.stdin.as_ref())?);
|
||||
|
|
Loading…
Reference in a new issue