blob: 2403100b7ab3d9d49be8094387f21205c1612f9c [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
Elly Jonese1749eb2011-10-07 13:54:59 -040014static void set_user(struct minijail *j, const char *arg)
15{
16 char *end = NULL;
17 int uid = strtod(arg, &end);
18 if (!*end && *arg) {
19 minijail_change_uid(j, uid);
20 return;
21 }
Elly Jonescd7a9042011-07-22 13:56:51 -040022
Elly Jonese1749eb2011-10-07 13:54:59 -040023 if (minijail_change_user(j, arg)) {
24 fprintf(stderr, "Bad user: '%s'\n", arg);
25 exit(1);
26 }
Elly Jonescd7a9042011-07-22 13:56:51 -040027}
28
Elly Jonese1749eb2011-10-07 13:54:59 -040029static void set_group(struct minijail *j, const char *arg)
30{
31 char *end = NULL;
32 int gid = strtod(arg, &end);
33 if (!*end && *arg) {
34 minijail_change_gid(j, gid);
35 return;
36 }
Elly Jonescd7a9042011-07-22 13:56:51 -040037
Elly Jonese1749eb2011-10-07 13:54:59 -040038 if (minijail_change_group(j, arg)) {
39 fprintf(stderr, "Bad group: '%s'\n", arg);
40 exit(1);
41 }
Elly Jonescd7a9042011-07-22 13:56:51 -040042}
43
Elly Jonese1749eb2011-10-07 13:54:59 -040044static void use_caps(struct minijail *j, const char *arg)
45{
46 uint64_t caps;
47 char *end = NULL;
48 caps = strtoull(arg, &end, 16);
49 if (*end) {
50 fprintf(stderr, "Invalid cap set: '%s'\n", arg);
51 exit(1);
52 }
53 minijail_use_caps(j, caps);
Elly Jonescd7a9042011-07-22 13:56:51 -040054}
55
Elly Jones51a5b6c2011-10-12 19:09:26 -040056static void add_binding(struct minijail *j, char *arg) {
57 char *src = strtok(arg, ",");
Elly Jones5ba42b52011-12-07 13:31:43 -050058 char *dest = strtok(NULL, ",");
59 char *flags = strtok(NULL, ",");
Elly Jones51a5b6c2011-10-12 19:09:26 -040060 if (!src || !dest) {
61 fprintf(stderr, "Bad binding: %s %s\n", src, dest);
62 exit(1);
63 }
64 if (minijail_bind(j, src, dest, flags ? atoi(flags) : 0)) {
65 fprintf(stderr, "Bind failure\n");
66 exit(1);
67 }
68}
69
Elly Jonese1749eb2011-10-07 13:54:59 -040070static void usage(const char *progn)
71{
Jorge Lucangeli Obesc2c9bcc2012-05-01 09:30:24 -070072 printf("Usage: %s [-Ghnprsv] [-b <src>,<dest>[,<writeable>]] "
73 "[-c <caps>] [-C <dir>] [-g <group>] [-S <file>] [-u <user>] "
74 "<program> [args...]\n"
Elly Jonesa8d1e1b2011-10-21 15:38:00 -040075 " -b: binds <src> to <dest> in chroot. Multiple "
76 "instances allowed\n"
Elly Jonese1749eb2011-10-07 13:54:59 -040077 " -c <caps>: restrict caps to <caps>\n"
Elly Jonesa8d1e1b2011-10-21 15:38:00 -040078 " -C <dir>: chroot to <dir>\n"
Elly Jonese1749eb2011-10-07 13:54:59 -040079 " -G: inherit secondary groups from uid\n"
80 " -g <group>: change gid to <group>\n"
81 " -h: help (this message)\n"
82 " -H: seccomp filter help message\n"
Jorge Lucangeli Obesc2c9bcc2012-05-01 09:30:24 -070083 " -n: set no_new_privs\n"
Elly Jonese58176c2012-01-23 11:46:17 -050084 " -p: use pid namespace (implies -vr)\n"
Elly Jonesfdd5f2d2012-01-23 13:27:43 -050085 " -r: remount /proc readonly (implies -v)\n"
Elly Jonese1749eb2011-10-07 13:54:59 -040086 " -s: use seccomp\n"
87 " -S <file>: set seccomp filters using <file>\n"
88 " E.g., -S /usr/share/filters/<prog>.$(uname -m)\n"
89 " -u <user>: change uid to <user>\n"
Jorge Lucangeli Obes2343d832012-04-25 21:59:48 -070090 " -v: use vfs namespace\n"
91 " -F: no dry run, force setting seccomp filters\n",
92 progn);
Elly Jonescd7a9042011-07-22 13:56:51 -040093}
94
Elly Jonese1749eb2011-10-07 13:54:59 -040095static void seccomp_filter_usage(const char *progn)
96{
97 const struct syscall_entry *entry = syscall_table;
98 printf("Usage: %s -S <policy.file> <program> [args...]\n\n"
99 "System call names supported:\n", progn);
100 for (; entry->name && entry->nr >= 0; ++entry)
101 printf(" %s [%d]\n", entry->name, entry->nr);
102 printf("\nSee minijail0(5) for example policies.\n");
Will Drewry32ac9f52011-08-18 21:36:27 -0500103}
104
Elly Jonese1749eb2011-10-07 13:54:59 -0400105int main(int argc, char *argv[])
106{
107 struct minijail *j = minijail_new();
Elly Jonescd7a9042011-07-22 13:56:51 -0400108
Elly Jonese1749eb2011-10-07 13:54:59 -0400109 int opt;
Jorge Lucangeli Obes2343d832012-04-25 21:59:48 -0700110 int use_seccomp_filter = 0;
111 int dry_run = 1;
Jorge Lucangeli Obesc2c9bcc2012-05-01 09:30:24 -0700112 while ((opt = getopt(argc, argv, "u:g:sS:c:C:b:vrGhHnpF")) != -1) {
Elly Jonese1749eb2011-10-07 13:54:59 -0400113 switch (opt) {
114 case 'u':
115 set_user(j, optarg);
116 break;
117 case 'g':
118 set_group(j, optarg);
119 break;
Jorge Lucangeli Obesc2c9bcc2012-05-01 09:30:24 -0700120 case 'n':
121 minijail_no_new_privs(j);
Elly Jonese1749eb2011-10-07 13:54:59 -0400122 case 's':
123 minijail_use_seccomp(j);
124 break;
125 case 'S':
126 minijail_parse_seccomp_filters(j, optarg);
127 minijail_use_seccomp_filter(j);
Jorge Lucangeli Obes2343d832012-04-25 21:59:48 -0700128 use_seccomp_filter = 1;
129 break;
130 case 'F':
131 dry_run = 0;
Elly Jonese1749eb2011-10-07 13:54:59 -0400132 break;
Elly Jones51a5b6c2011-10-12 19:09:26 -0400133 case 'b':
134 add_binding(j, optarg);
135 break;
Elly Jonese1749eb2011-10-07 13:54:59 -0400136 case 'c':
137 use_caps(j, optarg);
138 break;
Elly Jones51a5b6c2011-10-12 19:09:26 -0400139 case 'C':
140 minijail_enter_chroot(j, optarg);
141 break;
Elly Jonese1749eb2011-10-07 13:54:59 -0400142 case 'v':
143 minijail_namespace_vfs(j);
144 break;
145 case 'r':
146 minijail_remount_readonly(j);
147 break;
148 case 'G':
149 minijail_inherit_usergroups(j);
150 break;
151 case 'p':
152 minijail_namespace_pids(j);
153 break;
154 case 'H':
155 seccomp_filter_usage(argv[0]);
156 exit(1);
157 default:
158 usage(argv[0]);
159 exit(1);
160 }
161 }
Elly Jonescd7a9042011-07-22 13:56:51 -0400162
Jorge Lucangeli Obes2343d832012-04-25 21:59:48 -0700163 /* TODO(jorgelo): remove this when the seccomp BPF merge is done. */
164 if (use_seccomp_filter && !dry_run)
165 minijail_force_seccomp_filter(j);
166
Elly Jonese1749eb2011-10-07 13:54:59 -0400167 if (argc == optind) {
168 usage(argv[0]);
169 exit(1);
170 }
Elly Jonescd7a9042011-07-22 13:56:51 -0400171
Elly Jonese1749eb2011-10-07 13:54:59 -0400172 argc -= optind;
173 argv += optind;
Elly Jonescd7a9042011-07-22 13:56:51 -0400174
Elly Jonese1749eb2011-10-07 13:54:59 -0400175 minijail_run(j, argv[0], argv);
176 return minijail_wait(j);
Elly Jonescd7a9042011-07-22 13:56:51 -0400177}