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