Elly Jones | e58176c | 2012-01-23 11:46:17 -0500 | [diff] [blame] | 1 | /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
Elly Jones | cd7a904 | 2011-07-22 13:56:51 -0400 | [diff] [blame] | 2 | * Use of this source code is governed by a BSD-style license that can be |
Will Drewry | 32ac9f5 | 2011-08-18 21:36:27 -0500 | [diff] [blame] | 3 | * found in the LICENSE file. |
| 4 | */ |
Elly Jones | cd7a904 | 2011-07-22 13:56:51 -0400 | [diff] [blame] | 5 | |
Jorge Lucangeli Obes | 4b2d5ee | 2014-01-09 15:47:47 -0800 | [diff] [blame] | 6 | #include <dlfcn.h> |
Mike Frysinger | 68f7ccd | 2021-11-24 22:06:51 -0500 | [diff] [blame] | 7 | #include <err.h> |
Stephen Barber | 5dd5b1b | 2017-10-16 23:02:39 -0700 | [diff] [blame] | 8 | #include <errno.h> |
Elly Jones | cd7a904 | 2011-07-22 13:56:51 -0400 | [diff] [blame] | 9 | #include <stdio.h> |
| 10 | #include <stdlib.h> |
Elly Jones | cd7a904 | 2011-07-22 13:56:51 -0400 | [diff] [blame] | 11 | #include <unistd.h> |
| 12 | |
| 13 | #include "libminijail.h" |
| 14 | |
Lee Campbell | 1e4fc6a | 2014-06-06 17:40:02 -0700 | [diff] [blame] | 15 | #include "elfparse.h" |
Mike Frysinger | 5ef22ca | 2018-01-20 13:42:10 -0500 | [diff] [blame] | 16 | #include "minijail0_cli.h" |
Jorge Lucangeli Obes | bda833c | 2012-07-31 16:25:56 -0700 | [diff] [blame] | 17 | #include "util.h" |
| 18 | |
Stéphane Lesimple | f65da3a | 2022-01-11 11:44:47 +0100 | [diff] [blame] | 19 | int main(int argc, char *argv[], char *environ[]) |
Elly Fong-Jones | f65c9fe | 2013-01-22 13:55:02 -0500 | [diff] [blame] | 20 | { |
| 21 | struct minijail *j = minijail_new(); |
Jorge Lucangeli Obes | d99a40d | 2016-01-26 13:50:44 -0800 | [diff] [blame] | 22 | const char *dl_mesg = NULL; |
Luis Hector Chavez | 9acba45 | 2018-10-11 10:13:25 -0700 | [diff] [blame] | 23 | const char *preload_path = PRELOADPATH; |
Christopher Wiley | 88f76a7 | 2013-11-01 14:12:56 -0700 | [diff] [blame] | 24 | int exit_immediately = 0; |
Lee Campbell | 1e4fc6a | 2014-06-06 17:40:02 -0700 | [diff] [blame] | 25 | ElfType elftype = ELFERROR; |
Stéphane Lesimple | f65da3a | 2022-01-11 11:44:47 +0100 | [diff] [blame] | 26 | char **envp = NULL; |
| 27 | int consumed = parse_args(j, argc, argv, environ, |
| 28 | &exit_immediately, &elftype, |
| 29 | &preload_path, &envp); |
Elly Fong-Jones | f65c9fe | 2013-01-22 13:55:02 -0500 | [diff] [blame] | 30 | argc -= consumed; |
| 31 | argv += consumed; |
Jorge Lucangeli Obes | 482cb9d | 2014-07-23 15:16:04 -0700 | [diff] [blame] | 32 | |
Stephen Barber | 5dd5b1b | 2017-10-16 23:02:39 -0700 | [diff] [blame] | 33 | /* |
| 34 | * Make the process group ID of this process equal to its PID. |
| 35 | * In the non-interactive case (e.g. when minijail0 is started from |
| 36 | * init) this ensures the parent process and the jailed process |
| 37 | * can be killed together. |
| 38 | * |
| 39 | * Don't fail on EPERM, since setpgid(0, 0) can only EPERM when |
| 40 | * the process is already a process group leader. |
| 41 | */ |
| 42 | if (setpgid(0 /* use calling PID */, 0 /* make PGID = PID */)) { |
Mike Frysinger | 68f7ccd | 2021-11-24 22:06:51 -0500 | [diff] [blame] | 43 | if (errno != EPERM) |
| 44 | err(1, "setpgid(0, 0) failed"); |
Stephen Barber | 5dd5b1b | 2017-10-16 23:02:39 -0700 | [diff] [blame] | 45 | } |
| 46 | |
Lee Campbell | 1e4fc6a | 2014-06-06 17:40:02 -0700 | [diff] [blame] | 47 | if (elftype == ELFSTATIC) { |
Jorge Lucangeli Obes | 5471450 | 2015-09-30 10:08:45 -0700 | [diff] [blame] | 48 | /* |
| 49 | * Target binary is statically linked so we cannot use |
| 50 | * libminijailpreload.so. |
| 51 | */ |
| 52 | minijail_run_no_preload(j, argv[0], argv); |
Lee Campbell | 1e4fc6a | 2014-06-06 17:40:02 -0700 | [diff] [blame] | 53 | } else if (elftype == ELFDYNAMIC) { |
| 54 | /* |
| 55 | * Target binary is dynamically linked so we can |
| 56 | * inject libminijailpreload.so into it. |
| 57 | */ |
| 58 | |
| 59 | /* Check that we can dlopen() libminijailpreload.so. */ |
Luis Hector Chavez | 9acba45 | 2018-10-11 10:13:25 -0700 | [diff] [blame] | 60 | if (!dlopen(preload_path, RTLD_LAZY | RTLD_LOCAL)) { |
Matthew Dempsky | 2ed0912 | 2016-02-11 09:43:37 -0800 | [diff] [blame] | 61 | dl_mesg = dlerror(); |
Mike Frysinger | 68f7ccd | 2021-11-24 22:06:51 -0500 | [diff] [blame] | 62 | errx(1, "dlopen(): %s", dl_mesg); |
Matthew Dempsky | 2ed0912 | 2016-02-11 09:43:37 -0800 | [diff] [blame] | 63 | return 1; |
Lee Campbell | 1e4fc6a | 2014-06-06 17:40:02 -0700 | [diff] [blame] | 64 | } |
Luis Hector Chavez | 1790e28 | 2018-10-16 20:43:03 -0700 | [diff] [blame] | 65 | minijail_set_preload_path(j, preload_path); |
Stéphane Lesimple | f65da3a | 2022-01-11 11:44:47 +0100 | [diff] [blame] | 66 | if (envp) { |
| 67 | minijail_run_env(j, argv[0], argv, envp); |
| 68 | } else { |
| 69 | minijail_run(j, argv[0], argv); |
| 70 | } |
| 71 | } else { |
Mike Frysinger | 68f7ccd | 2021-11-24 22:06:51 -0500 | [diff] [blame] | 72 | errx(1, "Target program '%s' is not a valid ELF file", argv[0]); |
Stéphane Lesimple | f65da3a | 2022-01-11 11:44:47 +0100 | [diff] [blame] | 73 | } |
Lee Campbell | 1e4fc6a | 2014-06-06 17:40:02 -0700 | [diff] [blame] | 74 | |
Jorge Lucangeli Obes | beadf61 | 2019-03-20 09:32:15 -0400 | [diff] [blame] | 75 | if (exit_immediately) |
Christopher Wiley | 88f76a7 | 2013-11-01 14:12:56 -0700 | [diff] [blame] | 76 | return 0; |
Jorge Lucangeli Obes | beadf61 | 2019-03-20 09:32:15 -0400 | [diff] [blame] | 77 | |
lhchavez | 6c8d820 | 2017-09-01 03:55:11 +0000 | [diff] [blame] | 78 | int ret = minijail_wait(j); |
| 79 | #if defined(__SANITIZE_ADDRESS__) |
| 80 | minijail_destroy(j); |
| 81 | #endif /* __SANITIZE_ADDRESS__ */ |
| 82 | return ret; |
Elly Jones | cd7a904 | 2011-07-22 13:56:51 -0400 | [diff] [blame] | 83 | } |