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> g_minijail = LAZY_INSTANCE_INITIALIZER;
15 
Minijail()16 Minijail::Minijail() {}
17 
~Minijail()18 Minijail::~Minijail() {}
19 
20 // static
GetInstance()21 Minijail* Minijail::GetInstance() {
22   return g_minijail.Pointer();
23 }
24 
New()25 struct minijail* Minijail::New() {
26   return minijail_new();
27 }
28 
Destroy(struct minijail * jail)29 void Minijail::Destroy(struct minijail* jail) {
30   minijail_destroy(jail);
31 }
32 
DropRoot(struct minijail * jail,uid_t uid,gid_t gid)33 void Minijail::DropRoot(struct minijail* jail, uid_t uid, gid_t gid) {
34   minijail_change_uid(jail, uid);
35   minijail_change_gid(jail, gid);
36 }
37 
DropRoot(struct minijail * jail,const char * user,const char * group)38 bool Minijail::DropRoot(struct minijail* jail,
39                         const char* user,
40                         const char* group) {
41   // |user| and |group| are copied so the only reason either of these
42   // calls can fail is ENOMEM.
43   return !minijail_change_user(jail, user) &&
44          !minijail_change_group(jail, group);
45 }
46 
EnterNewPidNamespace(struct minijail * jail)47 void Minijail::EnterNewPidNamespace(struct minijail* jail) {
48   minijail_namespace_pids(jail);
49 }
50 
MountTmp(struct minijail * jail)51 void Minijail::MountTmp(struct minijail* jail) {
52   minijail_mount_tmp(jail);
53 }
54 
UseSeccompFilter(struct minijail * jail,const char * path)55 void Minijail::UseSeccompFilter(struct minijail* jail, const char* path) {
56   minijail_no_new_privs(jail);
57   minijail_use_seccomp_filter(jail);
58   minijail_parse_seccomp_filters(jail, path);
59 }
60 
UseCapabilities(struct minijail * jail,uint64_t capmask)61 void Minijail::UseCapabilities(struct minijail* jail, uint64_t capmask) {
62   minijail_use_caps(jail, capmask);
63 }
64 
ResetSignalMask(struct minijail * jail)65 void Minijail::ResetSignalMask(struct minijail* jail) {
66   minijail_reset_signal_mask(jail);
67 }
68 
Enter(struct minijail * jail)69 void Minijail::Enter(struct minijail* jail) {
70   minijail_enter(jail);
71 }
72 
Run(struct minijail * jail,vector<char * > args,pid_t * pid)73 bool Minijail::Run(struct minijail* jail, vector<char*> args, pid_t* pid) {
74   return minijail_run_pid(jail, args[0], args.data(), pid) == 0;
75 }
76 
RunSync(struct minijail * jail,vector<char * > args,int * status)77 bool Minijail::RunSync(struct minijail* jail, vector<char*> args, int* status) {
78   pid_t pid;
79   if (Run(jail, args, &pid) && waitpid(pid, status, 0) == pid) {
80     return true;
81   }
82 
83   return false;
84 }
85 
RunPipe(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin)86 bool Minijail::RunPipe(struct minijail* jail,
87                        vector<char*> args,
88                        pid_t* pid,
89                        int* stdin) {
90 #if defined(__ANDROID__)
91   return minijail_run_pid_pipes_no_preload(jail, args[0], args.data(), pid,
92                                            stdin, NULL, NULL) == 0;
93 #else
94   return minijail_run_pid_pipes(jail, args[0], args.data(), pid, stdin, NULL,
95                                 NULL) == 0;
96 #endif  // __ANDROID__
97 }
98 
RunPipes(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin,int * stdout,int * stderr)99 bool Minijail::RunPipes(struct minijail* jail,
100                         vector<char*> args,
101                         pid_t* pid,
102                         int* stdin,
103                         int* stdout,
104                         int* stderr) {
105 #if defined(__ANDROID__)
106   return minijail_run_pid_pipes_no_preload(jail, args[0], args.data(), pid,
107                                            stdin, stdout, stderr) == 0;
108 #else
109   return minijail_run_pid_pipes(jail, args[0], args.data(), pid, stdin, stdout,
110                                 stderr) == 0;
111 #endif  // __ANDROID__
112 }
113 
RunAndDestroy(struct minijail * jail,vector<char * > args,pid_t * pid)114 bool Minijail::RunAndDestroy(struct minijail* jail,
115                              vector<char*> args,
116                              pid_t* pid) {
117   bool res = Run(jail, args, pid);
118   Destroy(jail);
119   return res;
120 }
121 
RunSyncAndDestroy(struct minijail * jail,vector<char * > args,int * status)122 bool Minijail::RunSyncAndDestroy(struct minijail* jail,
123                                  vector<char*> args,
124                                  int* status) {
125   bool res = RunSync(jail, args, status);
126   Destroy(jail);
127   return res;
128 }
129 
RunPipeAndDestroy(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin)130 bool Minijail::RunPipeAndDestroy(struct minijail* jail,
131                                  vector<char*> args,
132                                  pid_t* pid,
133                                  int* stdin) {
134   bool res = RunPipe(jail, args, pid, stdin);
135   Destroy(jail);
136   return res;
137 }
138 
RunPipesAndDestroy(struct minijail * jail,vector<char * > args,pid_t * pid,int * stdin,int * stdout,int * stderr)139 bool Minijail::RunPipesAndDestroy(struct minijail* jail,
140                                   vector<char*> args,
141                                   pid_t* pid,
142                                   int* stdin,
143                                   int* stdout,
144                                   int* stderr) {
145   bool res = RunPipes(jail, args, pid, stdin, stdout, stderr);
146   Destroy(jail);
147   return res;
148 }
149 
150 }  // namespace brillo
151