blob: 9ab5195f41307704113fc0b4475e85be4f24ca95 [file] [log] [blame]
Elly Jonese58176c2012-01-23 11:46:17 -05001/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Elly Jonescd7a9042011-07-22 13:56:51 -04002 * Use of this source code is governed by a BSD-style license that can be
Will Drewry32ac9f52011-08-18 21:36:27 -05003 * found in the LICENSE file.
4 */
Elly Jonescd7a9042011-07-22 13:56:51 -04005
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10
11#include "libminijail.h"
Will Drewry32ac9f52011-08-18 21:36:27 -050012#include "libsyscalls.h"
Elly Jonescd7a9042011-07-22 13:56:51 -040013
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070014#include "util.h"
15
Elly Jonese1749eb2011-10-07 13:54:59 -040016static void set_user(struct minijail *j, const char *arg)
17{
18 char *end = NULL;
19 int uid = strtod(arg, &end);
20 if (!*end && *arg) {
21 minijail_change_uid(j, uid);
22 return;
23 }
Elly Jonescd7a9042011-07-22 13:56:51 -040024
Elly Jonese1749eb2011-10-07 13:54:59 -040025 if (minijail_change_user(j, arg)) {
26 fprintf(stderr, "Bad user: '%s'\n", arg);
27 exit(1);
28 }
Elly Jonescd7a9042011-07-22 13:56:51 -040029}
30
Elly Jonese1749eb2011-10-07 13:54:59 -040031static void set_group(struct minijail *j, const char *arg)
32{
33 char *end = NULL;
34 int gid = strtod(arg, &end);
35 if (!*end && *arg) {
36 minijail_change_gid(j, gid);
37 return;
38 }
Elly Jonescd7a9042011-07-22 13:56:51 -040039
Elly Jonese1749eb2011-10-07 13:54:59 -040040 if (minijail_change_group(j, arg)) {
41 fprintf(stderr, "Bad group: '%s'\n", arg);
42 exit(1);
43 }
Elly Jonescd7a9042011-07-22 13:56:51 -040044}
45
Elly Jonese1749eb2011-10-07 13:54:59 -040046static void use_caps(struct minijail *j, const char *arg)
47{
48 uint64_t caps;
49 char *end = NULL;
50 caps = strtoull(arg, &end, 16);
51 if (*end) {
52 fprintf(stderr, "Invalid cap set: '%s'\n", arg);
53 exit(1);
54 }
55 minijail_use_caps(j, caps);
Elly Jonescd7a9042011-07-22 13:56:51 -040056}
57
Elly Jones51a5b6c2011-10-12 19:09:26 -040058static void add_binding(struct minijail *j, char *arg) {
59 char *src = strtok(arg, ",");
Elly Jones5ba42b52011-12-07 13:31:43 -050060 char *dest = strtok(NULL, ",");
61 char *flags = strtok(NULL, ",");
Elly Jones51a5b6c2011-10-12 19:09:26 -040062 if (!src || !dest) {
63 fprintf(stderr, "Bad binding: %s %s\n", src, dest);
64 exit(1);
65 }
66 if (minijail_bind(j, src, dest, flags ? atoi(flags) : 0)) {
67 fprintf(stderr, "Bind failure\n");
68 exit(1);
69 }
70}
71
Elly Jonese1749eb2011-10-07 13:54:59 -040072static void usage(const char *progn)
73{
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070074 size_t i;
75
Jorge Lucangeli Obesc2c9bcc2012-05-01 09:30:24 -070076 printf("Usage: %s [-Ghnprsv] [-b <src>,<dest>[,<writeable>]] "
77 "[-c <caps>] [-C <dir>] [-g <group>] [-S <file>] [-u <user>] "
78 "<program> [args...]\n"
Elly Jonesa8d1e1b2011-10-21 15:38:00 -040079 " -b: binds <src> to <dest> in chroot. Multiple "
80 "instances allowed\n"
Elly Jonese1749eb2011-10-07 13:54:59 -040081 " -c <caps>: restrict caps to <caps>\n"
Elly Jonesa8d1e1b2011-10-21 15:38:00 -040082 " -C <dir>: chroot to <dir>\n"
Elly Jonese1749eb2011-10-07 13:54:59 -040083 " -G: inherit secondary groups from uid\n"
84 " -g <group>: change gid to <group>\n"
85 " -h: help (this message)\n"
86 " -H: seccomp filter help message\n"
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070087 " -L: log blocked syscalls when using seccomp filter. "
88 "Forces the following syscalls to be allowed:\n"
89 " ", progn);
90 for (i = 0; i < log_syscalls_len; i++)
91 printf("%s ", log_syscalls[i]);
92
93 printf("\n"
Jorge Lucangeli Obesc2c9bcc2012-05-01 09:30:24 -070094 " -n: set no_new_privs\n"
Elly Jonese58176c2012-01-23 11:46:17 -050095 " -p: use pid namespace (implies -vr)\n"
Elly Jonesfdd5f2d2012-01-23 13:27:43 -050096 " -r: remount /proc readonly (implies -v)\n"
Elly Jonese1749eb2011-10-07 13:54:59 -040097 " -s: use seccomp\n"
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070098 " -S <file>: set seccomp filter using <file>\n"
Elly Jonese1749eb2011-10-07 13:54:59 -040099 " E.g., -S /usr/share/filters/<prog>.$(uname -m)\n"
100 " -u <user>: change uid to <user>\n"
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -0700101 " -v: use vfs namespace\n");
Elly Jonescd7a9042011-07-22 13:56:51 -0400102}
103
Elly Jonese1749eb2011-10-07 13:54:59 -0400104static void seccomp_filter_usage(const char *progn)
105{
106 const struct syscall_entry *entry = syscall_table;
107 printf("Usage: %s -S <policy.file> <program> [args...]\n\n"
108 "System call names supported:\n", progn);
109 for (; entry->name && entry->nr >= 0; ++entry)
110 printf(" %s [%d]\n", entry->name, entry->nr);
111 printf("\nSee minijail0(5) for example policies.\n");
Will Drewry32ac9f52011-08-18 21:36:27 -0500112}
113
Elly Jonese1749eb2011-10-07 13:54:59 -0400114int main(int argc, char *argv[])
115{
116 struct minijail *j = minijail_new();
Elly Jonescd7a9042011-07-22 13:56:51 -0400117
Elly Jonese1749eb2011-10-07 13:54:59 -0400118 int opt;
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -0700119 while ((opt = getopt(argc, argv, "u:g:sS:c:C:b:vrGhHnpL")) != -1) {
Elly Jonese1749eb2011-10-07 13:54:59 -0400120 switch (opt) {
121 case 'u':
122 set_user(j, optarg);
123 break;
124 case 'g':
125 set_group(j, optarg);
126 break;
Jorge Lucangeli Obesc2c9bcc2012-05-01 09:30:24 -0700127 case 'n':
128 minijail_no_new_privs(j);
Jorge Lucangeli Obes0341d6c2012-07-16 15:27:31 -0700129 break;
Elly Jonese1749eb2011-10-07 13:54:59 -0400130 case 's':
131 minijail_use_seccomp(j);
132 break;
133 case 'S':
134 minijail_parse_seccomp_filters(j, optarg);
135 minijail_use_seccomp_filter(j);
136 break;
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -0700137 case 'L':
138 minijail_log_seccomp_filter_failures(j);
139 break;
Elly Jones51a5b6c2011-10-12 19:09:26 -0400140 case 'b':
141 add_binding(j, optarg);
142 break;
Elly Jonese1749eb2011-10-07 13:54:59 -0400143 case 'c':
144 use_caps(j, optarg);
145 break;
Elly Jones51a5b6c2011-10-12 19:09:26 -0400146 case 'C':
147 minijail_enter_chroot(j, optarg);
148 break;
Elly Jonese1749eb2011-10-07 13:54:59 -0400149 case 'v':
150 minijail_namespace_vfs(j);
151 break;
152 case 'r':
153 minijail_remount_readonly(j);
154 break;
155 case 'G':
156 minijail_inherit_usergroups(j);
157 break;
158 case 'p':
159 minijail_namespace_pids(j);
160 break;
161 case 'H':
162 seccomp_filter_usage(argv[0]);
163 exit(1);
164 default:
165 usage(argv[0]);
166 exit(1);
167 }
168 }
Elly Jonescd7a9042011-07-22 13:56:51 -0400169
Elly Jonese1749eb2011-10-07 13:54:59 -0400170 if (argc == optind) {
171 usage(argv[0]);
172 exit(1);
173 }
Elly Jonescd7a9042011-07-22 13:56:51 -0400174
Elly Jonese1749eb2011-10-07 13:54:59 -0400175 argc -= optind;
176 argv += optind;
Elly Jonescd7a9042011-07-22 13:56:51 -0400177
Elly Jonese1749eb2011-10-07 13:54:59 -0400178 minijail_run(j, argv[0], argv);
179 return minijail_wait(j);
Elly Jonescd7a9042011-07-22 13:56:51 -0400180}