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

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

Issue 2891933005: Plumb sandbox rules through the helper executable. (Closed)
Patch Set: Cleanup next round of feedback Created 3 years, 6 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 <string>
20 #include <vector>
21
22 #include "chrome/common/chrome_version.h"
23
24 #if defined(HELPER_EXECUTABLE)
25 #include "sandbox/mac/seatbelt_exec.h"
26 #endif // defined(HELPER_EXECUTABLE)
27
28 namespace {
29
30 typedef int (*ChromeMainPtr)(int, char**);
31
32 #if defined(HELPER_EXECUTABLE)
33 // The name of the parameter containing the executable path.
34 constexpr char exec_param[] = "EXECUTABLE_PATH";
Mark Mentovai 2017/05/24 20:42:42 Not really necessary for this to be out here, it c
Greg K 2017/05/25 17:52:05 Done.
35 // The name of the parameter containing the PID of Chrome.
36 constexpr char pid_param[] = "CHROMIUM_PID";
37 // The command line parameter to engage the v2 sandbox.
38 constexpr char v2_sandbox_arg[] = "--v2-sandbox";
39 // The command line parameter for the file descriptor used to receive the
40 // sandbox policy.
41 constexpr char fd_mapping_arg[] = "--fd_mapping=";
42
43 void SandboxExec(const char* exec_path,
Mark Mentovai 2017/05/24 20:42:41 Now you can make this __attribute__((noreturn)) wh
Greg K 2017/05/25 17:52:05 Done.
44 int argc,
45 char* argv[],
46 int fd_mapping) {
47 char rp[MAXPATHLEN];
48 if (realpath(argv[0], rp) == NULL)
Mark Mentovai 2017/05/24 20:42:41 Should we be using argv[0] or exec_path?
Greg K 2017/05/25 17:52:05 Done.
49 abort();
Mark Mentovai 2017/05/24 20:42:41 Did you want to perror() before abort() for things
Greg K 2017/05/25 17:52:05 Done.
50
51 sandbox::SeatbeltExecServer server(fd_mapping);
52
53 if (!server.SetParameter(exec_param, rp) ||
54 !server.SetParameter(pid_param, std::to_string(getpid()))) {
55 fprintf(stderr, "Failed to set up parameters for sandbox.\n");
56 abort();
57 }
58
59 if (server.InitializeSandbox() != 0)
60 abort();
Mark Mentovai 2017/05/24 20:42:41 And perhaps fprintf(stderr) something for things t
Greg K 2017/05/25 17:52:05 Done.
61
62 std::vector<char*> new_argv;
63 for (int i = 1; i < argc; ++i) {
64 if (strcmp(argv[i], v2_sandbox_arg) != 0 &&
65 strncmp(argv[i], fd_mapping_arg, strlen(fd_mapping_arg)) != 0) {
66 new_argv.push_back(argv[i]);
67 }
68 }
69 new_argv.push_back(nullptr);
70
71 // The helper executable re-executes itself under the sandbox.
72 execv(exec_path, new_argv.data());
73 perror("execve");
74 abort();
75 }
76 #endif // defined(HELPER_EXECUTABLE)
77
78 } // namespace
79
80 __attribute__((visibility("default"))) int main(int argc, char* argv[]) {
81 uint32_t exec_path_size = 0;
82 int rv = _NSGetExecutablePath(NULL, &exec_path_size);
83 if (rv != -1) {
84 fprintf(stderr, "_NSGetExecutablePath: get length failed\n");
85 abort();
86 }
87
88 char* exec_path = new char[exec_path_size];
89 rv = _NSGetExecutablePath(exec_path, &exec_path_size);
90 if (rv != 0) {
91 fprintf(stderr, "_NSGetExecutablePath: get path failed\n");
92 abort();
93 }
94
95 #if defined(HELPER_EXECUTABLE)
96 bool enable_v2_sandbox = false;
97 int fd_mapping = -1;
98 for (int i = 1; i < argc; i++) {
99 if (strcmp(argv[i], v2_sandbox_arg) == 0) {
100 enable_v2_sandbox = true;
101 } else if (strncmp(argv[i], fd_mapping_arg, strlen(fd_mapping_arg)) == 0) {
102 // Parse --fd_mapping=X to get the file descriptor X.
103 std::string arg(argv[i]);
104 std::string fd_str = arg.substr(strlen(fd_mapping_arg), arg.length());
105 fd_mapping = std::stoi(fd_str);
106 }
107 }
108 if (enable_v2_sandbox && fd_mapping == -1) {
109 fprintf(stderr, "Must pass a valid file descriptor to --fd_mapping.\n");
110 abort();
111 }
112
113 // SandboxExec either aborts or execs, but there is no return.
114 if (enable_v2_sandbox)
115 SandboxExec(exec_path, argc, argv, fd_mapping);
116
117 const char* const rel_path =
118 "../../../" PRODUCT_FULLNAME_STRING
119 " Framework.framework/" PRODUCT_FULLNAME_STRING " Framework";
120 #else
121 const char* const rel_path =
122 "../Versions/" CHROME_VERSION_STRING "/" PRODUCT_FULLNAME_STRING
123 " Framework.framework/" PRODUCT_FULLNAME_STRING " Framework";
124 #endif // defined(HELPER_EXECUTABLE)
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);
Mark Mentovai 2017/05/24 20:42:41 parent_dir_len instead of parent_path_len to make
Greg K 2017/05/25 17:52:05 Done.
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 snprintf(framework_path, framework_path_size, "%s/%s", parent_dir, rel_path);
141
142 void* library = dlopen(framework_path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
143 if (!library) {
144 fprintf(stderr, "dlopen %s: %s\n", framework_path, dlerror());
145 abort();
146 }
147 delete[] framework_path;
148
149 const ChromeMainPtr chrome_main =
150 reinterpret_cast<ChromeMainPtr>(dlsym(library, "ChromeMain"));
151 if (!chrome_main) {
152 fprintf(stderr, "dlsym ChromeMain: %s\n", dlerror());
153 abort();
154 }
155 rv = chrome_main(argc, argv);
156
157 // exit, don't return from main, to avoid the apparent removal of main from
158 // stack backtraces under tail call optimization.
159 exit(rv);
160 }
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