Skip to content

Commit dc0be29

Browse files
vmagrofacebook-github-bot
authored andcommitted
[antlir2][image_command_alias] variant that does not require actual userns unshare
Summary: Add a flag that allows running in a userns with only `root:root` mapped (to the unprivileged outer user). This is always allowed and does not depend on a working installation of `new(ug)idmap` in the environment. Test Plan: See next diff Reviewed By: CookieComputing Differential Revision: D83083848 fbshipit-source-id: abeb64ccf88a2f2d714c9989302759ddf20a29d7
1 parent a1777d2 commit dc0be29

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

antlir/antlir2/image_command_alias/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ rust_binary(
99
deps = [
1010
"anyhow",
1111
"clap",
12+
"nix",
1213
"tracing",
1314
"tracing-subscriber",
1415
"//antlir/antlir2/antlir2_isolate:antlir2_isolate",

antlir/antlir2/image_command_alias/image_command_alias.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def _impl(ctx: AnalysisContext) -> list[Provider] | Promise:
2020
cmd_args(root, format = "--root={}"),
2121
cmd_args(env_json, format = "--env={}") if env_json else cmd_args(),
2222
cmd_args(ctx.attrs.pass_env, format = "--pass-env={}"),
23+
"--single-user-userns" if ctx.attrs.single_user_userns else cmd_args(),
2324
"--",
2425
ctx.attrs.exe,
2526
cmd_args(ctx.attrs.args),
@@ -57,6 +58,14 @@ _image_command_alias = rule(
5758
"labels": attrs.list(attrs.string(), default = []),
5859
"pass_env": attrs.list(attrs.string(), default = []),
5960
"root": attrs.source(allow_directory = True),
61+
"single_user_userns": attrs.bool(
62+
default = False,
63+
doc = """
64+
If set, don't unshare into a fully remapped antlir userns, just
65+
unshare and map the current (ug)id to root and hope that it's
66+
good enough for what we're going to do (it usually is)
67+
""",
68+
),
6069
"_command_alias": attrs.default_only(attrs.exec_dep(default = "antlir//antlir/antlir2/image_command_alias:command_alias")),
6170
} | cfg_attrs(),
6271
cfg = layer_cfg,

antlir/antlir2/image_command_alias/src/main.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use anyhow::Result;
2020
use anyhow::ensure;
2121
use clap::Parser;
2222
use json_arg::JsonFile;
23+
use nix::unistd::Gid;
24+
use nix::unistd::Uid;
2325

2426
#[derive(Debug, Parser)]
2527
struct Args {
@@ -31,6 +33,11 @@ struct Args {
3133
env: Option<JsonFile<BTreeMap<String, Vec<String>>>>,
3234
#[clap(required(true), trailing_var_arg(true), allow_hyphen_values(true))]
3335
command: Vec<String>,
36+
#[clap(long)]
37+
/// If set, don't unshare into a fully remapped antlir userns, just unshare
38+
/// and map the current (ug)id to root and hope that it's good enough for
39+
/// what we're going to do (it usually is)
40+
single_user_userns: bool,
3441
}
3542

3643
fn main() -> Result<()> {
@@ -40,7 +47,21 @@ fn main() -> Result<()> {
4047
.with_max_level(tracing::Level::TRACE)
4148
.init();
4249

43-
antlir2_rootless::unshare_new_userns().context("while setting up userns")?;
50+
if !args.single_user_userns {
51+
antlir2_rootless::unshare_new_userns().context("while setting up userns")?;
52+
} else {
53+
let uid = Uid::current();
54+
let gid = Gid::current();
55+
nix::sched::unshare(nix::sched::CloneFlags::CLONE_NEWUSER)
56+
.context("while unsharing into new userns")?;
57+
std::fs::write("/proc/self/uid_map", format!("0 {uid} 1\n"))
58+
.context("while writing uid_map")?;
59+
nix::unistd::setuid(Uid::from_raw(0)).context("while setting uid to 0")?;
60+
std::fs::write("/proc/self/setgroups", "deny\n").context("while writing setgroups")?;
61+
std::fs::write("/proc/self/gid_map", format!("0 {gid} 1\n"))
62+
.context("while writing gid_map")?;
63+
nix::unistd::setgid(Gid::from_raw(0)).context("while setting gid to 0")?;
64+
}
4465

4566
let mut builder = IsolationContext::builder(&args.root);
4667
builder.ephemeral(true);

0 commit comments

Comments
 (0)