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

Side by Side Diff: chrome/common/service_process_util_mac.mm

Issue 982883003: Use fixed socket name instead of SecureSocketWithKey (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/service_process_util_posix.h" 5 #include "chrome/common/service_process_util_posix.h"
6 6
7 #import <Foundation/Foundation.h> 7 #import <Foundation/Foundation.h>
8 #include <launch.h> 8 #include <launch.h>
9 9
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/mac/bundle_locations.h" 15 #include "base/mac/bundle_locations.h"
16 #include "base/mac/foundation_util.h" 16 #include "base/mac/foundation_util.h"
17 #include "base/mac/mac_util.h" 17 #include "base/mac/mac_util.h"
18 #include "base/mac/scoped_nsautorelease_pool.h" 18 #include "base/mac/scoped_nsautorelease_pool.h"
19 #include "base/mac/scoped_nsobject.h" 19 #include "base/mac/scoped_nsobject.h"
20 #include "base/path_service.h" 20 #include "base/path_service.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
23 #include "base/strings/sys_string_conversions.h" 23 #include "base/strings/sys_string_conversions.h"
24 #include "base/threading/thread_restrictions.h" 24 #include "base/threading/thread_restrictions.h"
25 #include "base/version.h" 25 #include "base/version.h"
26 #include "chrome/common/chrome_paths.h" 26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/chrome_version_info.h" 28 #include "chrome/common/chrome_version_info.h"
29 #include "chrome/common/mac/launchd.h" 29 #include "chrome/common/mac/launchd.h"
30 #include "ipc/unix_domain_socket_util.h"
30 31
31 using ::base::FilePathWatcher; 32 using ::base::FilePathWatcher;
32 33
33 namespace { 34 namespace {
34 35
35 #define kServiceProcessSessionType "Aqua" 36 #define kServiceProcessSessionType "Aqua"
36 37
37 CFStringRef CopyServiceProcessLaunchDName() { 38 CFStringRef CopyServiceProcessLaunchDName() {
38 base::mac::ScopedNSAutoreleasePool pool; 39 base::mac::ScopedNSAutoreleasePool pool;
39 NSBundle* bundle = base::mac::FrameworkBundle(); 40 NSBundle* bundle = base::mac::FrameworkBundle();
40 return CFStringCreateCopy(kCFAllocatorDefault, 41 return CFStringCreateCopy(kCFAllocatorDefault,
41 base::mac::NSToCFCast([bundle bundleIdentifier])); 42 base::mac::NSToCFCast([bundle bundleIdentifier]));
42 } 43 }
43 44
44 NSString* GetServiceProcessLaunchDLabel() { 45 NSString* GetServiceProcessLaunchDLabel() {
45 base::scoped_nsobject<NSString> name( 46 base::scoped_nsobject<NSString> name(
46 base::mac::CFToNSCast(CopyServiceProcessLaunchDName())); 47 base::mac::CFToNSCast(CopyServiceProcessLaunchDName()));
47 NSString *label = [name stringByAppendingString:@".service_process"]; 48 NSString *label = [name stringByAppendingString:@".service_process"];
48 base::FilePath user_data_dir; 49 base::FilePath user_data_dir;
49 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 50 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
50 std::string user_data_dir_path = user_data_dir.value(); 51 std::string user_data_dir_path = user_data_dir.value();
51 NSString *ns_path = base::SysUTF8ToNSString(user_data_dir_path); 52 NSString *ns_path = base::SysUTF8ToNSString(user_data_dir_path);
52 ns_path = [ns_path stringByReplacingOccurrencesOfString:@" " 53 ns_path = [ns_path stringByReplacingOccurrencesOfString:@" "
53 withString:@"_"]; 54 withString:@"_"];
54 label = [label stringByAppendingString:ns_path]; 55 label = [label stringByAppendingString:ns_path];
55 return label; 56 return label;
56 } 57 }
57 58
58 NSString* GetServiceProcessLaunchDSocketKey() {
59 return @"ServiceProcessSocket";
60 }
61
62 bool GetParentFSRef(const FSRef& child, FSRef* parent) { 59 bool GetParentFSRef(const FSRef& child, FSRef* parent) {
63 return FSGetCatalogInfo(&child, 0, NULL, NULL, NULL, parent) == noErr; 60 return FSGetCatalogInfo(&child, 0, NULL, NULL, NULL, parent) == noErr;
64 } 61 }
65 62
66 bool RemoveFromLaunchd() { 63 bool RemoveFromLaunchd() {
67 // We're killing a file. 64 // We're killing a file.
68 base::ThreadRestrictions::AssertIOAllowed(); 65 base::ThreadRestrictions::AssertIOAllowed();
69 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); 66 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
70 return Launchd::GetInstance()->DeletePlist(Launchd::User, 67 return Launchd::GetInstance()->DeletePlist(Launchd::User,
71 Launchd::Agent, 68 Launchd::Agent,
72 name); 69 name);
73 } 70 }
74 71
75 class ExecFilePathWatcherCallback { 72 class ExecFilePathWatcherCallback {
76 public: 73 public:
77 ExecFilePathWatcherCallback() {} 74 ExecFilePathWatcherCallback() {}
78 ~ExecFilePathWatcherCallback() {} 75 ~ExecFilePathWatcherCallback() {}
79 76
80 bool Init(const base::FilePath& path); 77 bool Init(const base::FilePath& path);
81 void NotifyPathChanged(const base::FilePath& path, bool error); 78 void NotifyPathChanged(const base::FilePath& path, bool error);
82 79
83 private: 80 private:
84 FSRef executable_fsref_; 81 FSRef executable_fsref_;
85 }; 82 };
86 83
84 base::FilePath GetServiceProcessSocketName() {
85 base::FilePath socket_name;
86 PathService::Get(base::DIR_TEMP, &socket_name);
87 std::string pipe_name = GetServiceProcessScopedName("srv");
88 socket_name = socket_name.Append(pipe_name);
89 if (socket_name.value().size() < IPC::kMaxSocketNameLength)
90 return socket_name;
91 // Fallback to /tmp if $TMPDIR is too long.
Robert Sesek 2015/03/05 22:34:02 When would this happen?
Vitaly Buka (NO REVIEWS) 2015/03/05 23:22:13 kMaxSocketNameLength is 104 name generated on my
92 return base::FilePath("/tmp").Append(pipe_name);
93 }
94
87 } // namespace 95 } // namespace
88 96
89 NSString* GetServiceProcessLaunchDSocketEnvVar() {
90 NSString *label = GetServiceProcessLaunchDLabel();
91 NSString *env_var = [label stringByReplacingOccurrencesOfString:@"."
92 withString:@"_"];
93 env_var = [env_var stringByAppendingString:@"_SOCKET"];
94 env_var = [env_var uppercaseString];
95 return env_var;
96 }
97
98 // Gets the name of the service process IPC channel.
99 IPC::ChannelHandle GetServiceProcessChannel() { 97 IPC::ChannelHandle GetServiceProcessChannel() {
100 base::mac::ScopedNSAutoreleasePool pool; 98 base::FilePath socket_name = GetServiceProcessSocketName();
101 std::string socket_path; 99 VLOG(1) << "ServiceProcessChannel: " << socket_name.value();
102 base::scoped_nsobject<NSDictionary> dictionary( 100 return IPC::ChannelHandle(socket_name.value());
103 base::mac::CFToNSCast(Launchd::GetInstance()->CopyExports()));
104 NSString *ns_socket_path =
105 [dictionary objectForKey:GetServiceProcessLaunchDSocketEnvVar()];
106 if (ns_socket_path) {
107 socket_path = base::SysNSStringToUTF8(ns_socket_path);
108 }
109 return IPC::ChannelHandle(socket_path);
110 } 101 }
111 102
112 bool ForceServiceProcessShutdown(const std::string& /* version */, 103 bool ForceServiceProcessShutdown(const std::string& /* version */,
113 base::ProcessId /* process_id */) { 104 base::ProcessId /* process_id */) {
114 base::mac::ScopedNSAutoreleasePool pool; 105 base::mac::ScopedNSAutoreleasePool pool;
115 CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel()); 106 CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel());
116 CFErrorRef err = NULL; 107 CFErrorRef err = NULL;
117 bool ret = Launchd::GetInstance()->RemoveJob(label, &err); 108 bool ret = Launchd::GetInstance()->RemoveJob(label, &err);
118 if (!ret) { 109 if (!ret) {
119 DLOG(ERROR) << "ForceServiceProcessShutdown: " << err << " " 110 DLOG(ERROR) << "ForceServiceProcessShutdown: " << err << " "
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 DLOG(ERROR) << "ServiceProcess must be launched by launchd. " 169 DLOG(ERROR) << "ServiceProcess must be launched by launchd. "
179 << "CopyLaunchdDictionaryByCheckingIn: " << err; 170 << "CopyLaunchdDictionaryByCheckingIn: " << err;
180 CFRelease(err); 171 CFRelease(err);
181 return false; 172 return false;
182 } 173 }
183 state_->launchd_conf.reset(dict); 174 state_->launchd_conf.reset(dict);
184 return true; 175 return true;
185 } 176 }
186 177
187 IPC::ChannelHandle ServiceProcessState::GetServiceProcessChannel() { 178 IPC::ChannelHandle ServiceProcessState::GetServiceProcessChannel() {
188 DCHECK(state_); 179 return ::GetServiceProcessChannel();
189 NSDictionary *ns_launchd_conf = base::mac::CFToNSCast(state_->launchd_conf);
190 NSDictionary* socket_dict =
191 [ns_launchd_conf objectForKey:@ LAUNCH_JOBKEY_SOCKETS];
192 NSArray* sockets =
193 [socket_dict objectForKey:GetServiceProcessLaunchDSocketKey()];
194 DCHECK_EQ([sockets count], 1U);
195 int socket = [[sockets objectAtIndex:0] intValue];
196 base::FileDescriptor fd(socket, false);
197 return IPC::ChannelHandle(std::string(), fd);
198 } 180 }
199 181
200 bool CheckServiceProcessReady() { 182 bool CheckServiceProcessReady() {
201 std::string version; 183 std::string version;
202 pid_t pid; 184 pid_t pid;
203 if (!GetServiceProcessData(&version, &pid)) { 185 if (!GetServiceProcessData(&version, &pid) || pid == -1) {
204 return false; 186 return false;
205 } 187 }
206 Version service_version(version); 188 Version service_version(version);
207 bool ready = true; 189 bool ready = true;
208 if (!service_version.IsValid()) { 190 if (!service_version.IsValid()) {
209 ready = false; 191 ready = false;
210 } else { 192 } else {
211 chrome::VersionInfo version_info; 193 chrome::VersionInfo version_info;
212 Version running_version(version_info.Version()); 194 Version running_version(version_info.Version());
213 if (!running_version.IsValid()) { 195 if (!running_version.IsValid()) {
(...skipping 22 matching lines...) Expand all
236 218
237 std::vector<std::string> args = cmd_line->argv(); 219 std::vector<std::string> args = cmd_line->argv();
238 NSMutableArray *ns_args = [NSMutableArray arrayWithCapacity:args.size()]; 220 NSMutableArray *ns_args = [NSMutableArray arrayWithCapacity:args.size()];
239 221
240 for (std::vector<std::string>::iterator iter = args.begin(); 222 for (std::vector<std::string>::iterator iter = args.begin();
241 iter < args.end(); 223 iter < args.end();
242 ++iter) { 224 ++iter) {
243 [ns_args addObject:base::SysUTF8ToNSString(*iter)]; 225 [ns_args addObject:base::SysUTF8ToNSString(*iter)];
244 } 226 }
245 227
246 NSDictionary *socket =
247 [NSDictionary dictionaryWithObject:GetServiceProcessLaunchDSocketEnvVar()
248 forKey:@ LAUNCH_JOBSOCKETKEY_SECUREWITHKEY];
249 NSDictionary *sockets =
250 [NSDictionary dictionaryWithObject:socket
251 forKey:GetServiceProcessLaunchDSocketKey()];
252
253 // See the man page for launchd.plist. 228 // See the man page for launchd.plist.
254 NSMutableDictionary *launchd_plist = 229 NSMutableDictionary *launchd_plist =
255 [[NSMutableDictionary alloc] initWithObjectsAndKeys: 230 [[NSMutableDictionary alloc] initWithObjectsAndKeys:
256 GetServiceProcessLaunchDLabel(), @ LAUNCH_JOBKEY_LABEL, 231 GetServiceProcessLaunchDLabel(), @ LAUNCH_JOBKEY_LABEL,
257 program, @ LAUNCH_JOBKEY_PROGRAM, 232 program, @ LAUNCH_JOBKEY_PROGRAM,
258 ns_args, @ LAUNCH_JOBKEY_PROGRAMARGUMENTS, 233 ns_args, @ LAUNCH_JOBKEY_PROGRAMARGUMENTS,
259 sockets, @ LAUNCH_JOBKEY_SOCKETS, 234 [NSNumber numberWithBool:YES], @ LAUNCH_JOBKEY_RUNATLOAD,
Robert Sesek 2015/03/05 22:34:02 This is changing the RunAtLoad to be from only whe
Robert Sesek 2015/03/05 22:34:02 You can use @YES
Vitaly Buka (NO REVIEWS) 2015/03/05 23:22:13 Done.
Vitaly Buka (NO REVIEWS) 2015/03/05 23:22:13 for_auto_launch means that this file is going to b
260 nil]; 235 nil];
261 236
262 if (for_auto_launch) { 237 if (for_auto_launch) {
263 // We want the service process to be able to exit if there are no services 238 // We want the service process to be able to exit if there are no services
264 // enabled. With a value of NO in the SuccessfulExit key, launchd will 239 // enabled. With a value of NO in the SuccessfulExit key, launchd will
265 // relaunch the service automatically in any other case than exiting 240 // relaunch the service automatically in any other case than exiting
266 // cleanly with a 0 return code. 241 // cleanly with a 0 return code.
267 NSDictionary *keep_alive = 242 NSDictionary *keep_alive =
268 [NSDictionary 243 [NSDictionary
269 dictionaryWithObject:[NSNumber numberWithBool:NO] 244 dictionaryWithObject:[NSNumber numberWithBool:NO]
270 forKey:@ LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT]; 245 forKey:@ LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT];
271 NSDictionary *auto_launchd_plist = 246 NSDictionary *auto_launchd_plist =
272 [[NSDictionary alloc] initWithObjectsAndKeys: 247 [[NSDictionary alloc] initWithObjectsAndKeys:
273 [NSNumber numberWithBool:YES], @ LAUNCH_JOBKEY_RUNATLOAD,
274 keep_alive, @ LAUNCH_JOBKEY_KEEPALIVE, 248 keep_alive, @ LAUNCH_JOBKEY_KEEPALIVE,
275 @ kServiceProcessSessionType, @ LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE, 249 @ kServiceProcessSessionType, @ LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE,
276 nil]; 250 nil];
277 [launchd_plist addEntriesFromDictionary:auto_launchd_plist]; 251 [launchd_plist addEntriesFromDictionary:auto_launchd_plist];
278 } 252 }
279 return reinterpret_cast<CFDictionaryRef>(launchd_plist); 253 return reinterpret_cast<CFDictionaryRef>(launchd_plist);
280 } 254 }
281 255
282 // Writes the launchd property list into the user's LaunchAgents directory, 256 // Writes the launchd property list into the user's LaunchAgents directory,
283 // creating that directory if needed. This will cause the service process to be 257 // creating that directory if needed. This will cause the service process to be
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 CFErrorRef err = NULL; 408 CFErrorRef err = NULL;
435 if (!Launchd::GetInstance()->RemoveJob(label, &err)) { 409 if (!Launchd::GetInstance()->RemoveJob(label, &err)) {
436 base::ScopedCFTypeRef<CFErrorRef> scoped_err(err); 410 base::ScopedCFTypeRef<CFErrorRef> scoped_err(err);
437 DLOG(ERROR) << "RemoveJob " << err; 411 DLOG(ERROR) << "RemoveJob " << err;
438 // Exiting with zero, so launchd doesn't restart the process. 412 // Exiting with zero, so launchd doesn't restart the process.
439 exit(0); 413 exit(0);
440 } 414 }
441 } 415 }
442 } 416 }
443 } 417 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698