Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: chrome/app/chrome_exe_main_mac.cc

Issue 2891933005: Plumb sandbox rules through the helper executable. (Closed)
Patch Set: Switch to new and delete Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/app/chrome_exe_main_mac.c ('k') | sandbox/mac/sandbox_mac_seatbelt_exec_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium 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 // The entry point for all Mac Chromium processes, including the outer app
6 // bundle (browser) and helper app (renderer, plugin, and friends).
7
8 #include <dlfcn.h>
9 #include <errno.h>
10 #include <libgen.h>
11 #include <mach-o/dyld.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18
19 #include <vector>
20
21 #include "chrome/common/chrome_version.h"
22
23 #if defined(HELPER_EXECUTABLE)
24 #include "sandbox/mac/seatbelt_exec.h"
25 #endif // defined(HELPER_EXECUTABLE)
26
27 namespace {
28
29 typedef int (*ChromeMainPtr)(int, char**);
30
31 #if defined(HELPER_EXECUTABLE)
32 // The name of the parameter containing the executable path.
33 constexpr char exec_param[] = "EXECUTABLE_PATH";
Mark Mentovai 2017/05/22 18:53:18 WHY ARE WE YELLING?
Greg K 2017/05/22 23:17:55 All sandbox parameters are written in uppercase, s
34 // The name of the parameter containing the PID of Chrome.
35 constexpr char pid_param[] = "CHROMIUM_PID";
36 // The command line parameter to engage the v2 sandbox.
37 constexpr char v2_sandbox_arg[] = "--v2-sandbox";
38 // The command line parameter for the file descriptor used to receive the
39 // sandbox policy.
40 constexpr char fd_mapping_arg[] = "--fd_mapping";
41
42 int SandboxExec(int argc, char* argv[], int fd_mapping) {
43 char rp[MAXPATHLEN];
44 if (realpath(argv[0], rp) == NULL)
45 abort();
46
47 sandbox::SeatbeltExecServer server(fd_mapping);
48
49 if (!server.SetParameter(exec_param, rp) ||
50 !server.SetParameter(pid_param, std::to_string(getpid()))) {
Mark Mentovai 2017/05/22 18:53:17 #include <string>
Greg K 2017/05/22 23:17:55 Done.
51 fprintf(stderr, "Failed to setup parameters for sandbox.\n");
Mark Mentovai 2017/05/22 18:53:18 “set up”
Greg K 2017/05/22 23:17:55 Done.
52 return -1;
53 }
54
55 if (server.InitializeSandbox() != 0)
56 abort();
57
58 std::vector<char*> new_argv;
59 for (int i = 1; i < argc; ++i) {
60 if (strcmp(argv[i], v2_sandbox_arg) != 0 &&
61 strncmp(argv[i], fd_mapping_arg, strlen(fd_mapping_arg)) != 0) {
Mark Mentovai 2017/05/22 18:53:18 Shouldn’t you be looking for “--fd_mapping=”?
Greg K 2017/05/22 23:17:55 Done.
62 new_argv.push_back(argv[i]);
63 }
64 }
65 new_argv.push_back(nullptr);
66
67 // The helper executable re-executes itself under the sandbox.
68 execve(argv[0], new_argv.data(), nullptr);
Mark Mentovai 2017/05/22 18:53:18 Why is envp nullptr?
Greg K 2017/05/22 23:17:55 Good catch, it needs to pass the current environme
69 perror("execve");
70 return 1;
71 }
72 #endif // defined(HELPER_EXECUTABLE)
73
74 } // namespace
75
76 __attribute__((visibility("default"))) int main(int argc, char* argv[]) {
77 #if defined(HELPER_EXECUTABLE)
78 bool enable_v2_sandbox = false;
79 int fd_mapping = -1;
80 for (int i = 1; i < argc; i++) {
81 if (strcmp(argv[i], v2_sandbox_arg) == 0) {
82 enable_v2_sandbox = true;
83 } else if (strncmp(argv[i], fd_mapping_arg, strlen(fd_mapping_arg)) == 0) {
84 // Parse --fd_mapping=X to get the file descriptor X.
85 std::string arg(argv[i]);
86 std::string fd_str = arg.substr(arg.find("=") + 1, arg.length());
87 fd_mapping = std::stoi(fd_str);
Mark Mentovai 2017/05/22 18:53:18 This piece of junk will return 0 if fd_str isn’t r
Greg K 2017/05/22 23:17:55 libc++abi.dylib: terminating with uncaught excepti
88 }
89 }
90 if (enable_v2_sandbox && fd_mapping == -1) {
91 fprintf(stderr, "Must pass a valid file descriptor to --fd_mapping.\n");
92 return -1;
93 }
94
95 if (enable_v2_sandbox)
96 return SandboxExec(argc, argv, fd_mapping);
97
98 const char* const rel_path =
99 "../../../" PRODUCT_FULLNAME_STRING
100 " Framework.framework/" PRODUCT_FULLNAME_STRING " Framework";
101 #else
102 const char* const rel_path =
103 "../Versions/" CHROME_VERSION_STRING "/" PRODUCT_FULLNAME_STRING
104 " Framework.framework/" PRODUCT_FULLNAME_STRING " Framework";
105 #endif // defined(HELPER_EXECUTABLE)
106
107 uint32_t exec_path_size = 0;
108 int rv = _NSGetExecutablePath(NULL, &exec_path_size);
109 if (rv != -1) {
110 fprintf(stderr, "_NSGetExecutablePath: get length failed\n");
111 abort();
112 }
113
114 char* exec_path = new char[exec_path_size];
115 if (!exec_path) {
Greg K 2017/05/22 18:34:03 I know Chrome doesn't use exceptions, but the unde
Mark Mentovai 2017/05/22 18:53:17 Right.
116 fprintf(stderr, "new %u failed.\n", exec_path_size);
117 abort();
118 }
119
120 rv = _NSGetExecutablePath(exec_path, &exec_path_size);
121 if (rv != 0) {
122 fprintf(stderr, "_NSGetExecutablePath: get path failed\n");
123 abort();
124 }
125
126 // Slice off the last part of the main executable path, and append the
127 // version framework information.
128 const char* parent_dir = dirname(exec_path);
129 if (!parent_dir) {
130 fprintf(stderr, "dirname %s: %s\n", exec_path, strerror(errno));
131 abort();
132 }
133 delete[] exec_path;
134
135 const size_t parent_path_len = strlen(parent_dir);
136 const size_t rel_path_len = strlen(rel_path);
137 // 2 accounts for a trailing NUL byte and the '/' in the middle of the paths.
138 const size_t framework_path_size = parent_path_len + rel_path_len + 2;
139 char* framework_path = new char[framework_path_size];
140 if (!framework_path) {
141 fprintf(stderr, "new %zu failed.\n", framework_path_size);
142 abort();
143 }
144 snprintf(framework_path, framework_path_size, "%s/%s", parent_dir, rel_path);
Greg K 2017/05/22 18:34:03 Unless there's a good reason to prefer C style for
Mark Mentovai 2017/05/22 18:53:18 Greg K wrote:
Greg K 2017/05/22 23:17:55 Acknowledged.
145
146 void* library = dlopen(framework_path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
147 if (!library) {
148 fprintf(stderr, "dlopen %s: %s\n", framework_path, dlerror());
149 abort();
150 }
151 delete[] framework_path;
152
153 const ChromeMainPtr chrome_main =
154 reinterpret_cast<ChromeMainPtr>(dlsym(library, "ChromeMain"));
155 if (!chrome_main) {
156 fprintf(stderr, "dlsym ChromeMain: %s\n", dlerror());
157 abort();
158 }
159 rv = chrome_main(argc, argv);
160
161 // exit, don't return from main, to avoid the apparent removal of main from
162 // stack backtraces under tail call optimization.
163 exit(rv);
164 }
OLDNEW
« no previous file with comments | « chrome/app/chrome_exe_main_mac.c ('k') | sandbox/mac/sandbox_mac_seatbelt_exec_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698