aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2022-01-26 12:06:38 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-01-26 12:06:38 +0000
commit471bcd8b5af9953b88ef55cb1e8c37d69621686e (patch)
tree0360a77d9f705b80b50e5e225254394daeca9a9b
parent496b4c966511497687fe02501527f0f45c185629 (diff)
parent26ae20c491876f81d4df2e0325b55d3b2c9a6e9b (diff)
downloadminijail-471bcd8b5af9953b88ef55cb1e8c37d69621686e.tar.gz
cli: rewrite usage output am: e16ab3ed5f am: 72ad6b243e am: 8121dfee44 am: 26ae20c491
Original change: https://android-review.googlesource.com/c/platform/external/minijail/+/1959588 Change-Id: I5bc548cdf5e326d9a65479c5fa9c0271eec94339
-rw-r--r--minijail0_cli.c273
1 files changed, 148 insertions, 125 deletions
diff --git a/minijail0_cli.c b/minijail0_cli.c
index 36afc36..54cfdb7 100644
--- a/minijail0_cli.c
+++ b/minijail0_cli.c
@@ -472,111 +472,156 @@ enum {
OPT_UTS,
};
+/*
+ * NB: When adding new options, prefer long-option only. Add a short option
+ * only if its meaning is intuitive/obvious at a glance.
+ *
+ * Keep this sorted.
+ */
+static const char optstring[] =
+ "+a:b:c:de::f:g:hik:lm::nprst::u:vwyzB:C:GHIK::LM::NP:R:S:T:UV:Y";
+
+static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"mount-dev", no_argument, 0, 'd'},
+ {"ambient", no_argument, 0, OPT_AMBIENT},
+ {"uts", optional_argument, 0, OPT_UTS},
+ {"logging", required_argument, 0, OPT_LOGGING},
+ {"profile", required_argument, 0, OPT_PROFILE},
+ {"preload-library", required_argument, 0, OPT_PRELOAD_LIBRARY},
+ {"seccomp-bpf-binary", required_argument, 0, OPT_SECCOMP_BPF_BINARY},
+ {"add-suppl-group", required_argument, 0, OPT_ADD_SUPPL_GROUP},
+ {"allow-speculative-execution", no_argument, 0,
+ OPT_ALLOW_SPECULATIVE_EXECUTION},
+ {"config", required_argument, 0, OPT_CONFIG},
+ {"mount", required_argument, 0, 'k'},
+ {"bind-mount", required_argument, 0, 'b'},
+ {0, 0, 0, 0},
+};
+
+/*
+ * Pull the usage string out into the top-level to help with long-lines. We
+ * want the output to be wrapped at 80 cols when it's shown to the user in the
+ * terminal, but we don't want the source wrapped to 80 cols because that will
+ * effectively make terminal output wrap to much lower levels (like <70).
+ */
+/* clang-format off */
+static const char help_text[] =
+"Account (user/group) options:\n"
+" -u <user> Change uid to <user>.\n"
+" -g <group> Change gid to <group>.\n"
+" -G Inherit supplementary groups from new uid.\n"
+" Incompatible with -y or --add-suppl-group.\n"
+" -y Keep original uid's supplementary groups.\n"
+" Incompatible with -G or --add-suppl-group.\n"
+" --add-suppl-group <group>\n"
+" Add <group> to the proccess' supplementary groups.\n"
+" Can be specified multiple times to add several groups.\n"
+" Incompatible with -y or -G.\n"
+"\n"
+"Mount/path options:\n"
+" -b <src[,dst[,writable]]>, --bind-mount <...>\n"
+" Bind <src> to <dst>.\n"
+" -k <src,dst,fstype[,flags[,data]]>, --mount <...>\n"
+" Mount <src> at <dst>. <flags> and <data> can be specified as\n"
+" in mount(2). Multiple instances allowed.\n"
+" -K Do not change share mode of any existing mounts.\n"
+" -K<mode> Mark all existing mounts as <mode> instead of MS_PRIVATE.\n"
+" -r Remount /proc read-only (implies -v).\n"
+" -d, --mount-dev\n"
+" Create a new /dev with a minimal set of device nodes\n"
+" (implies -v). See minijail0(1) for exact list.\n"
+" -t[size] Mount tmpfs at /tmp (implies -v).\n"
+" Optional argument specifies size (default \"64M\").\n"
+" -C <dir> chroot(2) to <dir>. Incompatible with -P.\n"
+" -P <dir> pivot_root(2) to <dir> (implies -v). Incompatible with -C.\n"
+"\n"
+"Namespace options:\n"
+" -N Enter a new cgroup namespace.\n"
+" -l Enter new IPC namespace.\n"
+" -v Enter new mount namespace.\n"
+" -V <file> Enter specified mount namespace.\n"
+" -e[file] Enter new network namespace, or existing |file| if provided.\n"
+" -p Enter new pid namespace (implies -vr).\n"
+" -I Run as init (pid 1) inside a new pid namespace (implies -p).\n"
+" -U Enter new user namespace (implies -p).\n"
+" -m[<uid> <loweruid> <count>]\n"
+" Set the uid map of a user namespace (implies -pU).\n"
+" Same arguments as newuidmap(1); mappings are comma separated.\n"
+" With no mapping, map the current uid to root.\n"
+" Incompatible with -b without the 'writable' option.\n"
+" -M[<gid> <lowergid> <count>]\n"
+" Set the gid map of a user namespace (implies -pU).\n"
+" Same arguments as newgidmap(1); mappings are comma separated.\n"
+" With no mapping, map the current gid to root.\n"
+" Incompatible with -b without the 'writable' option.\n"
+" --uts[=name] Enter a new UTS namespace (and set hostname).\n"
+"\n"
+"Seccomp options:\n"
+" -S <file> Set seccomp filter using <file>.\n"
+" E.g., '-S /usr/share/filters/<prog>.$(uname -m)'.\n"
+" Requires -n when not running as root.\n"
+" --seccomp-bpf-binary=<f>\n"
+" Set a pre-compiled seccomp filter using <f>.\n"
+" E.g., '-S /usr/share/filters/<prog>.$(uname -m).bpf'.\n"
+" Requires -n when not running as root.\n"
+" The user is responsible for ensuring that the binary\n"
+" was compiled for the correct architecture / kernel version.\n"
+" -L Report blocked syscalls when using seccomp filter.\n"
+" If the kernel does not support SECCOMP_RET_LOG, some syscalls\n"
+" will automatically be allowed (see below).\n"
+" -Y Synchronize seccomp filters across thread group.\n"
+" -a <table> Use alternate syscall table <table>.\n"
+" -s Use seccomp mode 1 (not the same as -S).\n"
+"\n"
+"Other options:\n"
+" --config <file>\n"
+" Load the Minijail configuration file <file>.\n"
+" If used, must be specified ahead of other options.\n"
+" --profile <p>\n"
+" Configure minijail0 to run with the <p> sandboxing profile,\n"
+" which is a convenient way to express multiple flags\n"
+" that are typically used together.\n"
+" See the minijail0(1) man page for the full list.\n"
+" -n Set no_new_privs. See prctl(2) for details.\n"
+" -c <caps> Restrict caps to <caps>.\n"
+" --ambient Raise ambient capabilities. Requires -c.\n"
+" -B <mask> Skip setting <mask> securebits when restricting caps (-c).\n"
+" By default, SECURE_NOROOT, SECURE_NO_SETUID_FIXUP, and \n"
+" SECURE_KEEP_CAPS (with their respective locks) are set.\n"
+" -f <file> Write the pid of the jailed process to <file>.\n"
+" -i Exit immediately after fork(2); i.e. background the program.\n"
+" -z Don't forward signals to jailed process.\n"
+" -R <type,cur,max>\n"
+" Call setrlimit(3); can be specified multiple times.\n"
+" -T <type> Assume <program> is a <type> ELF binary;\n"
+" <type> may be 'static' or 'dynamic'.\n"
+" This will avoid accessing <program> binary before execve(2).\n"
+" Type 'static' will avoid preload hooking.\n"
+" -w Create and join a new anonymous session keyring.\n"
+"\n"
+"Uncommon options:\n"
+" --allow-speculative-execution\n"
+" Allow speculative execution by disabling mitigations.\n"
+" --preload-library=<file>\n"
+" Overrides the path to \"" PRELOADPATH "\".\n"
+" This is only really useful for local testing.\n"
+" --logging=<output>\n"
+" Set the logging system output: 'auto' (default),\n"
+" 'syslog', or 'stderr'.\n"
+" -h Help (this message).\n"
+" -H Seccomp filter help message.\n";
+/* clang-format on */
+
static void usage(const char *progn)
{
- size_t i;
- /* clang-format off */
- printf("Usage: %s [-dGhHiIKlLnNprRstUvyYz]\n"
- " [-a <table>]\n"
- " [-b <src>[,[dest][,<writeable>]]] [-k <src>,<dest>,<type>[,<flags>[,<data>]]]\n"
- " [-c <caps>] [-C <dir>] [-P <dir>] [-e[file]] [-f <file>] [-g <group>]\n"
- " [-m[<uid> <loweruid> <count>]*] [-M[<gid> <lowergid> <count>]*] [--profile <name>]\n"
- " [-R <type,cur,max>] [-S <file>] [-t[size]] [-T <type>] [-u <user>] [-V <file>]\n"
- " <program> [args...]\n"
- " -a <table>: Use alternate syscall table <table>.\n"
- " --bind-mount <...>, Bind <src> to <dest> in chroot.\n"
- " -b <...>: Multiple instances allowed.\n"
- " -B <mask>: Skip setting securebits in <mask> when restricting capabilities (-c).\n"
- " By default, SECURE_NOROOT, SECURE_NO_SETUID_FIXUP, and \n"
- " SECURE_KEEP_CAPS (together with their respective locks) are set.\n"
- " There are eight securebits in total.\n"
- " --mount <...>,Mount <src> at <dest> in chroot.\n"
- " -k <...>:<flags> and <data> can be specified as in mount(2).\n"
- " Multiple instances allowed.\n"
- " -c <caps>: Restrict caps to <caps>.\n"
- " -C <dir>: chroot(2) to <dir>.\n"
- " Not compatible with -P.\n"
- " -P <dir>: pivot_root(2) to <dir> (implies -v).\n"
- " Not compatible with -C.\n"
- " --mount-dev, Create a new /dev with a minimal set of device nodes (implies -v).\n"
- " -d: See the minijail0(1) man page for the exact set.\n"
- " -e[file]: Enter new network namespace, or existing one if |file| is provided.\n"
- " -f <file>: Write the pid of the jailed process to <file>.\n"
- " -g <group>: Change gid to <group>.\n"
- " -G: Inherit supplementary groups from new uid.\n"
- " Not compatible with -y or --add-suppl-group.\n"
- " -y: Keep original uid's supplementary groups.\n"
- " Not compatible with -G or --add-suppl-group.\n"
- " --add-suppl-group <g>:Add <g> to the proccess' supplementary groups,\n"
- " can be specified multiple times to add several groups.\n"
- " Not compatible with -y or -G.\n"
- " -h: Help (this message).\n"
- " -H: Seccomp filter help message.\n"
- " -i: Exit immediately after fork(2). The jailed process will run\n"
- " in the background.\n"
- " -I: Run <program> as init (pid 1) inside a new pid namespace (implies -p).\n"
- " -K: Do not change share mode of any existing mounts.\n"
- " -K<mode>: Mark all existing mounts as <mode> instead of MS_PRIVATE.\n"
- " -l: Enter new IPC namespace.\n"
- " -L: Report blocked syscalls when using seccomp filter.\n"
- " If the kernel does not support SECCOMP_RET_LOG,\n"
- " forces the following syscalls to be allowed:\n"
- " ", progn);
- /* clang-format on */
- for (i = 0; i < log_syscalls_len; i++)
- printf("%s ", log_syscalls[i]);
-
- /* clang-format off */
- printf("\n"
- " -m[map]: Set the uid map of a user namespace (implies -pU).\n"
- " Same arguments as newuidmap(1), multiple mappings should be separated by ',' (comma).\n"
- " With no mapping, map the current uid to root inside the user namespace.\n"
- " Not compatible with -b without the 'writable' option.\n"
- " -M[map]: Set the gid map of a user namespace (implies -pU).\n"
- " Same arguments as newgidmap(1), multiple mappings should be separated by ',' (comma).\n"
- " With no mapping, map the current gid to root inside the user namespace.\n"
- " Not compatible with -b without the 'writable' option.\n"
- " -n: Set no_new_privs.\n"
- " -N: Enter a new cgroup namespace.\n"
- " -p: Enter new pid namespace (implies -vr).\n"
- " -r: Remount /proc read-only (implies -v).\n"
- " -R: Set rlimits, can be specified multiple times.\n"
- " -s: Use seccomp mode 1 (not the same as -S).\n"
- " -S <file>: Set seccomp filter using <file>.\n"
- " E.g., '-S /usr/share/filters/<prog>.$(uname -m)'.\n"
- " Requires -n when not running as root.\n"
- " -t[size]: Mount tmpfs at /tmp (implies -v).\n"
- " Optional argument specifies size (default \"64M\").\n"
- " -T <type>: Assume <program> is a <type> ELF binary; <type> can be 'static' or 'dynamic'.\n"
- " This will avoid accessing <program> binary before execve(2).\n"
- " Type 'static' will avoid preload hooking.\n"
- " -u <user>: Change uid to <user>.\n"
- " -U: Enter new user namespace (implies -p).\n"
- " -v: Enter new mount namespace.\n"
- " -V <file>: Enter specified mount namespace.\n"
- " -w: Create and join a new anonymous session keyring.\n"
- " -Y: Synchronize seccomp filters across thread group.\n"
- " -z: Don't forward signals to jailed process.\n"
- " --ambient: Raise ambient capabilities. Requires -c.\n"
- " --uts[=name]: Enter a new UTS namespace (and set hostname).\n"
- " --logging=<s>:Use <s> as the logging system.\n"
- " <s> must be 'auto' (default), 'syslog', or 'stderr'.\n"
- " --profile <p>:Configure minijail0 to run with the <p> sandboxing profile,\n"
- " which is a convenient way to express multiple flags\n"
- " that are typically used together.\n"
- " See the minijail0(1) man page for the full list.\n"
- " --preload-library=<f>:Overrides the path to \"" PRELOADPATH "\".\n"
- " This is only really useful for local testing.\n"
- " --seccomp-bpf-binary=<f>:Set a pre-compiled seccomp filter using <f>.\n"
- " E.g., '-S /usr/share/filters/<prog>.$(uname -m).bpf'.\n"
- " Requires -n when not running as root.\n"
- " The user is responsible for ensuring that the binary\n"
- " was compiled for the correct architecture / kernel version.\n"
- " --allow-speculative-execution:Allow speculative execution and disable\n"
- " mitigations for speculative execution attacks.\n"
- " --config <file>:Load the Minijail configuration file <file>.\n"
- " If used, must be specified ahead of other options.\n");
- /* clang-format on */
+ printf("Usage: %s [options] [--] <program> [args...]\n\n%s", progn,
+ help_text);
+
+ printf("\nsyscalls allowed when logging (-L):\n ");
+ for (size_t i = 0; i < log_syscalls_len; ++i)
+ printf(" %s", log_syscalls[i]);
+ printf("\n");
}
static void seccomp_filter_usage(const char *progn)
@@ -640,28 +685,6 @@ static int getopt_conf_or_cli(int argc, char *const argv[],
size_t *conf_index)
{
int opt = -1;
- /* NB: Keep short list sorted. */
- static const char optstring[] =
- "+a:b:c:de::f:g:hik:lm::nprst::u:vwyzB:C:GHIK::LM::NP:R:S:T:UV:Y";
- /* clang-format off */
- static const struct option long_options[] = {
- {"help", no_argument, 0, 'h'},
- {"mount-dev", no_argument, 0, 'd'},
- {"ambient", no_argument, 0, OPT_AMBIENT},
- {"uts", optional_argument, 0, OPT_UTS},
- {"logging", required_argument, 0, OPT_LOGGING},
- {"profile", required_argument, 0, OPT_PROFILE},
- {"preload-library", required_argument, 0, OPT_PRELOAD_LIBRARY},
- {"seccomp-bpf-binary", required_argument, 0, OPT_SECCOMP_BPF_BINARY},
- {"add-suppl-group", required_argument, 0, OPT_ADD_SUPPL_GROUP},
- {"allow-speculative-execution", no_argument, 0,
- OPT_ALLOW_SPECULATIVE_EXECUTION},
- {"config", required_argument, 0, OPT_CONFIG},
- {"mount", required_argument, 0, 'k'},
- {"bind-mount", required_argument, 0, 'b'},
- {0, 0, 0, 0},
- };
- /* clang-format on */
if (*conf_entry_list != NULL)
opt =
getopt_from_conf(long_options, conf_entry_list, conf_index);