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; |
} |