Chromium Code Reviews| Index: content/renderer/renderer_main_platform_delegate_mac.mm |
| diff --git a/content/renderer/renderer_main_platform_delegate_mac.mm b/content/renderer/renderer_main_platform_delegate_mac.mm |
| index 9f6172e71e1ff7800de39c96c4a5e36cbc57287c..9a66421785063e2d2bc2e5ee7d67c0116976c317 100644 |
| --- a/content/renderer/renderer_main_platform_delegate_mac.mm |
| +++ b/content/renderer/renderer_main_platform_delegate_mac.mm |
| @@ -13,6 +13,7 @@ |
| #import "base/mac/foundation_util.h" |
| #import "base/mac/mac_util.h" |
| #include "base/mac/scoped_cftyperef.h" |
| +#include "base/strings/string_number_conversions.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "content/common/sandbox_mac.h" |
| #include "content/public/common/content_switches.h" |
| @@ -68,6 +69,69 @@ void CrRendererCFLog(int32_t level, CFStringRef format, ...) { |
| va_end(args); |
| } |
| +// You are about to read a pretty disgusting hack. In a static initializer, |
| +// CoreFoundation decides to connect with cfprefsd(8) using Mach IPC. There is |
| +// no public way to close this Mach port after-the-fact, nor a way to stop it |
| +// from happening since it is done pre-main in dyld. But the address of the |
| +// CFMachPort can be found in the run loop's string description. Below, that |
| +// address is parsed, cast, and then used to invalidate the Mach port to |
| +// disable communication with cfprefsd. |
| +void DisconnectCFNotificationCenter() { |
| + base::ScopedCFTypeRef<CFStringRef> description( |
|
Mark Mentovai
2014/02/25 17:08:41
You also have port_description in this function. T
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + CFCopyDescription(CFRunLoopGetCurrent())); |
|
Mark Mentovai
2014/02/25 17:08:41
A comment with the full contents of what this stri
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + const CFIndex length = CFStringGetLength(description); |
| + for (CFIndex i = 0; i < length; ) { |
| + // Find the start of a CFMachPort run loop source. |
| + CFRange start_range; |
|
Mark Mentovai
2014/02/25 17:08:41
There are a few different ranges in here. This one
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + if (!CFStringFindWithOptions(description, CFSTR("context = <CFMachPort "), |
| + CFRangeMake(i, length - i), 0, &start_range)) { |
| + break; |
| + } |
| + i = start_range.location + start_range.length; |
| + |
| + // The address of the CFMachPort is the first hexadecimal address after the |
| + // CF type name. |
| + CFRange address_range = CFRangeMake(i, 0); |
| + for (CFIndex j = start_range.location; i < length - j; ++j) { |
|
Mark Mentovai
2014/02/25 17:08:41
“i is less than length minus j”
Do you think that
Robert Sesek
2014/02/25 17:56:30
Wow that was doltish of me. This is the problem wi
|
| + UniChar c = CFStringGetCharacterAtIndex(description, j); |
| + ++address_range.length; |
|
Mark Mentovai
2014/02/25 17:08:41
Don’t you want to do this after breaking on ' '?
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + if (c == ' ') |
|
Mark Mentovai
2014/02/25 17:08:41
If you never found the space, you might have a tru
Robert Sesek
2014/02/25 17:56:30
I don't think this condition is likely at all, and
|
| + break; |
| + } |
| + |
| + // The address is a hexadecimal string. |
| + if (address_range.length < 1) |
|
Mark Mentovai
2014/02/25 17:08:41
If you passed through the loop above at all, even
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + continue; |
| + |
| + base::ScopedCFTypeRef<CFStringRef> address_string( |
| + CFStringCreateWithSubstring(NULL, description, address_range)); |
| + if (!address_string) |
| + continue; |
| + |
| + // Convert the string to an address. |
| + std::string address_std_string = base::SysCFStringRefToUTF8(address_string); |
| + uint64 address = 0; |
|
Mark Mentovai
2014/02/25 17:08:41
Marginal preference for
#if __LP64__
// this th
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + if (!base::HexStringToUInt64(address_std_string, &address)) |
| + continue; |
| + |
| + // Cast the address to an object. |
| + CFMachPortRef mach_port = reinterpret_cast<CFMachPortRef>(address); |
|
Mark Mentovai
2014/02/25 17:08:41
if (CFGetTypeID(mach_port) != CFMachPortGetTypeID(
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + |
| + // Verify that this is the Mach port that needs to be disconnected by the |
| + // name of its callout function. |
| + base::ScopedCFTypeRef<CFStringRef> port_description( |
| + CFCopyDescription(mach_port)); |
|
Mark Mentovai
2014/02/25 17:08:41
Contents comment for this one too?
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + if (CFStringFindWithOptions(port_description, |
| + CFSTR("callout = __CFXNotificationReceiveFromServer"), |
|
Mark Mentovai
2014/02/25 17:08:41
Anchor this string with a trailing space.
Maybe e
Robert Sesek
2014/02/25 17:56:30
Done.
|
| + CFRangeMake(0, CFStringGetLength(port_description)), |
| + 0, |
| + NULL)) { |
| + CFMachPortInvalidate(mach_port); |
| + return; |
| + } |
| + } |
| +} |
| + |
| } // namespace |
| RendererMainPlatformDelegate::RendererMainPlatformDelegate( |
| @@ -173,6 +237,8 @@ bool RendererMainPlatformDelegate::EnableSandbox() { |
| source_list, arraysize(source_list), &kCFTypeArrayCallBacks); |
| } |
| + DisconnectCFNotificationCenter(); |
| + |
| return sandbox_initialized; |
| } |