1*4b9c6d91SCole Faust /* Copyright 2012 The ChromiumOS Authors
2*4b9c6d91SCole Faust * Use of this source code is governed by a BSD-style license that can be
3*4b9c6d91SCole Faust * found in the LICENSE file.
4*4b9c6d91SCole Faust */
5*4b9c6d91SCole Faust
6*4b9c6d91SCole Faust #include <dlfcn.h>
7*4b9c6d91SCole Faust #include <err.h>
8*4b9c6d91SCole Faust #include <errno.h>
9*4b9c6d91SCole Faust #include <stdio.h>
10*4b9c6d91SCole Faust #include <stdlib.h>
11*4b9c6d91SCole Faust #include <unistd.h>
12*4b9c6d91SCole Faust
13*4b9c6d91SCole Faust #include "libminijail.h"
14*4b9c6d91SCole Faust
15*4b9c6d91SCole Faust #include "elfparse.h"
16*4b9c6d91SCole Faust #include "minijail0_cli.h"
17*4b9c6d91SCole Faust #include "util.h"
18*4b9c6d91SCole Faust
main(int argc,char * argv[],char * environ[])19*4b9c6d91SCole Faust int main(int argc, char *argv[], char *environ[])
20*4b9c6d91SCole Faust {
21*4b9c6d91SCole Faust struct minijail *j = minijail_new();
22*4b9c6d91SCole Faust const char *dl_mesg = NULL;
23*4b9c6d91SCole Faust const char *preload_path = PRELOADPATH;
24*4b9c6d91SCole Faust int exit_immediately = 0;
25*4b9c6d91SCole Faust ElfType elftype = ELFERROR;
26*4b9c6d91SCole Faust char **envp = NULL;
27*4b9c6d91SCole Faust int consumed = parse_args(j, argc, argv, environ,
28*4b9c6d91SCole Faust &exit_immediately, &elftype,
29*4b9c6d91SCole Faust &preload_path, &envp);
30*4b9c6d91SCole Faust argc -= consumed;
31*4b9c6d91SCole Faust argv += consumed;
32*4b9c6d91SCole Faust
33*4b9c6d91SCole Faust /*
34*4b9c6d91SCole Faust * Make the process group ID of this process equal to its PID.
35*4b9c6d91SCole Faust * In the non-interactive case (e.g. when minijail0 is started from
36*4b9c6d91SCole Faust * init) this ensures the parent process and the jailed process
37*4b9c6d91SCole Faust * can be killed together.
38*4b9c6d91SCole Faust *
39*4b9c6d91SCole Faust * Don't fail on EPERM, since setpgid(0, 0) can only EPERM when
40*4b9c6d91SCole Faust * the process is already a process group leader.
41*4b9c6d91SCole Faust */
42*4b9c6d91SCole Faust if (setpgid(0 /* use calling PID */, 0 /* make PGID = PID */)) {
43*4b9c6d91SCole Faust if (errno != EPERM)
44*4b9c6d91SCole Faust err(1, "setpgid(0, 0) failed");
45*4b9c6d91SCole Faust }
46*4b9c6d91SCole Faust
47*4b9c6d91SCole Faust if (elftype == ELFSTATIC) {
48*4b9c6d91SCole Faust /*
49*4b9c6d91SCole Faust * Target binary is statically linked so we cannot use
50*4b9c6d91SCole Faust * libminijailpreload.so.
51*4b9c6d91SCole Faust */
52*4b9c6d91SCole Faust minijail_run_no_preload(j, argv[0], argv);
53*4b9c6d91SCole Faust } else if (elftype == ELFDYNAMIC) {
54*4b9c6d91SCole Faust /*
55*4b9c6d91SCole Faust * Target binary is dynamically linked so we can
56*4b9c6d91SCole Faust * inject libminijailpreload.so into it.
57*4b9c6d91SCole Faust */
58*4b9c6d91SCole Faust
59*4b9c6d91SCole Faust /* Check that we can dlopen() libminijailpreload.so. */
60*4b9c6d91SCole Faust if (!dlopen(preload_path, RTLD_LAZY | RTLD_LOCAL)) {
61*4b9c6d91SCole Faust dl_mesg = dlerror();
62*4b9c6d91SCole Faust errx(1, "dlopen(): %s", dl_mesg);
63*4b9c6d91SCole Faust return 1;
64*4b9c6d91SCole Faust }
65*4b9c6d91SCole Faust minijail_set_preload_path(j, preload_path);
66*4b9c6d91SCole Faust if (envp) {
67*4b9c6d91SCole Faust minijail_run_env(j, argv[0], argv, envp);
68*4b9c6d91SCole Faust } else {
69*4b9c6d91SCole Faust minijail_run(j, argv[0], argv);
70*4b9c6d91SCole Faust }
71*4b9c6d91SCole Faust } else {
72*4b9c6d91SCole Faust errx(1, "Target program '%s' is not a valid ELF file", argv[0]);
73*4b9c6d91SCole Faust }
74*4b9c6d91SCole Faust
75*4b9c6d91SCole Faust if (exit_immediately)
76*4b9c6d91SCole Faust return 0;
77*4b9c6d91SCole Faust
78*4b9c6d91SCole Faust int ret = minijail_wait(j);
79*4b9c6d91SCole Faust #if defined(__SANITIZE_ADDRESS__)
80*4b9c6d91SCole Faust minijail_destroy(j);
81*4b9c6d91SCole Faust #endif /* __SANITIZE_ADDRESS__ */
82*4b9c6d91SCole Faust return ret;
83*4b9c6d91SCole Faust }
84