1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "brillo/minijail/minijail.h"
6
7 #include <sys/types.h>
8 #include <sys/wait.h>
9
10 using std::vector;
11
12 namespace brillo {
13
14 static base::LazyInstance<Minijail>::DestructorAtExit g_minijail
15 = LAZY_INSTANCE_INITIALIZER;
16
Minijail()17 Minijail::Minijail() {}
18
~Minijail()19 Minijail::~Minijail() {}
20
21 // static
GetInstance()22 Minijail* Minijail::GetInstance() {
23 static Minijail* minijail = new Minijail();
24 return minijail;
25 }
26
New()27 struct minijail* Minijail::New() {
28 return minijail_new();
29 }
30
Destroy(struct minijail * jail)31 void Minijail::Destroy(struct minijail* jail) {
32 minijail_destroy(jail);
33 }
34
DropRoot(struct minijail * jail,uid_t uid,gid_t gid)35 void Minijail::DropRoot(struct minijail* jail, uid_t uid, gid_t gid) {
36 minijail_change_uid(jail, uid);
37 minijail_change_gid(jail, gid);
38 }
39
DropRoot(struct minijail * jail,const char * user,const char * group)40 bool Minijail::DropRoot(struct minijail* jail,
41 const char* user,
42 const char* group) {
43 // |user| and |group| are copied so the only reason either of these
44 // calls can fail is ENOMEM.
45 return !minijail_change_user(jail, user) &&
46 !minijail_change_group(jail, group);
47 }
48
EnterNewPidNamespace(struct minijail * jail)49 void Minijail::EnterNewPidNamespace(struct minijail* jail) {
50 minijail_namespace_pids(jail);
51 }
52
MountTmp(struct minijail * jail)53 void Minijail::MountTmp(struct minijail* jail) {
54 minijail_mount_tmp(jail);
55 }
56
UseSeccompFilter(struct minijail * jail,const char * path)57 void Minijail::UseSeccompFilter(struct minijail* jail, const char* path) {
58 minijail_no_new_privs(jail);
59 minijail_use_seccomp_filter(jail);
60 minijail_parse_seccomp_filters(jail, path);
61 }
62
UseCapabilities(struct minijail * jail,uint64_t capmask)63 void Minijail::UseCapabilities(struct minijail* jail, uint64_t capmask) {
64 minijail_use_caps(jail, capmask);
65 }
66
ResetSignalMask(struct minijail * jail)67 void Minijail::ResetSignalMask(struct minijail* jail) {
68 minijail_reset_signal_mask(jail);
69 }
70
CloseOpenFds(struct minijail * jail)71 void Minijail::CloseOpenFds(struct minijail* jail) {
72 minijail_close_open_fds(jail);
73 }
74
PreserveFd(struct minijail * jail,int parent_fd,int child_fd)75 void Minijail::PreserveFd(struct minijail* jail, int parent_fd, int child_fd) {
76 minijail_preserve_fd(jail, parent_fd, child_fd);
77 }
78
Enter(struct minijail * jail)79 void Minijail::Enter(struct minijail* jail) {
80 minijail_enter(jail);
81 }
82
Run(struct minijail * jail,vector<char * > args,pid_t * pid)83 bool Minijail::Run(struct minijail* jail, vector<char*> args, pid_t* pid) {
84 return minijail_run_pid(jail, args[0], args.data(), pid) == 0;
85 }
86
RunSync(struct minijail * jail,vector<char * > args,int * status)87 bool Minijail::RunSync(struct minijail* jail, vector<char*> args, int* status) {
88 pid_t pid;
89 if (Run(jail, args, &pid) && waitpid(pid, status, 0) == pid) {
90 return true;
91 }
92
93 return false;
94 }
95
RunPipe(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin)96 bool Minijail::RunPipe(struct minijail* jail,
97 vector<char*> args,
98 pid_t* pid,
99 int* stdin) {
100 #if defined(__ANDROID__)
101 return minijail_run_pid_pipes_no_preload(jail, args[0], args.data(), pid,
102 stdin, NULL, NULL) == 0;
103 #else
104 return minijail_run_pid_pipes(jail, args[0], args.data(), pid, stdin, NULL,
105 NULL) == 0;
106 #endif // __ANDROID__
107 }
108
RunPipes(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin,int * stdout,int * stderr)109 bool Minijail::RunPipes(struct minijail* jail,
110 vector<char*> args,
111 pid_t* pid,
112 int* stdin,
113 int* stdout,
114 int* stderr) {
115 #if defined(__ANDROID__)
116 return minijail_run_pid_pipes_no_preload(jail, args[0], args.data(), pid,
117 stdin, stdout, stderr) == 0;
118 #else
119 return minijail_run_pid_pipes(jail, args[0], args.data(), pid, stdin, stdout,
120 stderr) == 0;
121 #endif // __ANDROID__
122 }
123
RunEnvPipes(struct minijail * jail,vector<char * > args,vector<char * > env,pid_t * pid,int * stdin,int * stdout,int * stderr)124 bool Minijail::RunEnvPipes(struct minijail* jail,
125 vector<char*> args,
126 vector<char*> env,
127 pid_t* pid,
128 int* stdin,
129 int* stdout,
130 int* stderr) {
131 #if defined(__ANDROID__)
132 return minijail_run_env_pid_pipes_no_preload(jail, args[0], args.data(),
133 env.data(), pid, stdin, stdout,
134 stderr) == 0;
135 #else
136 return minijail_run_env_pid_pipes(jail, args[0], args.data(), env.data(), pid,
137 stdin, stdout, stderr) == 0;
138 #endif // __ANDROID__
139 }
140
RunAndDestroy(struct minijail * jail,vector<char * > args,pid_t * pid)141 bool Minijail::RunAndDestroy(struct minijail* jail,
142 vector<char*> args,
143 pid_t* pid) {
144 bool res = Run(jail, args, pid);
145 Destroy(jail);
146 return res;
147 }
148
RunSyncAndDestroy(struct minijail * jail,vector<char * > args,int * status)149 bool Minijail::RunSyncAndDestroy(struct minijail* jail,
150 vector<char*> args,
151 int* status) {
152 bool res = RunSync(jail, args, status);
153 Destroy(jail);
154 return res;
155 }
156
RunPipeAndDestroy(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin)157 bool Minijail::RunPipeAndDestroy(struct minijail* jail,
158 vector<char*> args,
159 pid_t* pid,
160 int* stdin) {
161 bool res = RunPipe(jail, args, pid, stdin);
162 Destroy(jail);
163 return res;
164 }
165
RunPipesAndDestroy(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin,int * stdout,int * stderr)166 bool Minijail::RunPipesAndDestroy(struct minijail* jail,
167 vector<char*> args,
168 pid_t* pid,
169 int* stdin,
170 int* stdout,
171 int* stderr) {
172 bool res = RunPipes(jail, args, pid, stdin, stdout, stderr);
173 Destroy(jail);
174 return res;
175 }
176
RunEnvPipesAndDestroy(struct minijail * jail,vector<char * > args,vector<char * > env,pid_t * pid,int * stdin,int * stdout,int * stderr)177 bool Minijail::RunEnvPipesAndDestroy(struct minijail* jail,
178 vector<char*> args,
179 vector<char*> env,
180 pid_t* pid,
181 int* stdin,
182 int* stdout,
183 int* stderr) {
184 bool res = RunEnvPipes(jail, args, env, pid, stdin, stdout, stderr);
185 Destroy(jail);
186 return res;
187 }
188
189 } // namespace brillo
190