OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #import "chrome/browser/chrome_browser_application_mac.h" | 5 #import "chrome/browser/chrome_browser_application_mac.h" |
6 | 6 |
7 #import "base/logging.h" | 7 #import "base/logging.h" |
8 #import "base/mac/mac_util.h" | 8 #import "base/mac/mac_util.h" |
9 #import "base/mac/scoped_nsexception_enabler.h" | 9 #import "base/mac/scoped_nsexception_enabler.h" |
10 #import "base/metrics/histogram.h" | 10 #import "base/metrics/histogram.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 118 } |
119 | 119 |
120 // Forward to the original version. | 120 // Forward to the original version. |
121 return gOriginalInitIMP(self, _cmd, aName, aReason, someUserInfo); | 121 return gOriginalInitIMP(self, _cmd, aName, aReason, someUserInfo); |
122 } | 122 } |
123 @end | 123 @end |
124 | 124 |
125 static IMP gOriginalNSBundleLoadIMP = NULL; | 125 static IMP gOriginalNSBundleLoadIMP = NULL; |
126 | 126 |
127 @interface NSBundle (CrNSBundleSwizzle) | 127 @interface NSBundle (CrNSBundleSwizzle) |
| 128 // -crLoad swizzles -load. It refuses to load parasitic third-party code |
| 129 // located in certain directories, returning NO instead of attempting to load |
| 130 // the bundle. This circumvents some of the mechanisms that third-party code |
| 131 // attempts to use to inject itself into applications. Note that some of these |
| 132 // mechanisms are unavailable to 64-bit applications anyway. |
128 - (BOOL)crLoad; | 133 - (BOOL)crLoad; |
129 @end | 134 @end |
130 | 135 |
131 @implementation NSBundle (CrNSBundleSwizzle) | 136 @implementation NSBundle (CrNSBundleSwizzle) |
132 - (BOOL)crLoad { | 137 - (BOOL)crLoad { |
133 // Method only called when swizzled. | 138 // Method only called when swizzled. |
134 DCHECK(_cmd == @selector(load)); | 139 DCHECK(_cmd == @selector(load)); |
135 | 140 |
136 // MultiClutchInputManager is broken in Chrome on Lion. | 141 // ~/Library, /Library, and /Network/Library. Things in /System/Library |
137 // http://crbug.com/90075. | 142 // aren't blacklisted. |
138 if (base::mac::IsOSLionOrLater() && | 143 NSArray* blockedPrefixes = |
139 [[self bundleIdentifier] | 144 NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, |
140 isEqualToString:@"net.wonderboots.multiclutchinputmanager"]) { | 145 NSUserDomainMask | |
141 return NO; | 146 NSLocalDomainMask | |
| 147 NSNetworkDomainMask, |
| 148 YES); |
| 149 |
| 150 // Everything in the suffix list has a trailing slash so as to only block |
| 151 // loading things contained in these directories. |
| 152 NSString* const blockedSuffixes[] = { |
| 153 // SIMBL - http://code.google.com/p/simbl/source/browse/src/SIMBL.{h,m}. |
| 154 // It attempts to inject itself via an AppleScript event. |
| 155 // http://code.google.com/p/simbl/source/browse/SIMBL%20Agent/SIMBLAgent.m |
| 156 @"Application Support/SIMBL/Plugins/", |
| 157 |
| 158 #if !defined(__LP64__) |
| 159 // Contextual menu manager plug-ins are unavailable to 64-bit processes. |
| 160 // http://developer.apple.com/library/mac/releasenotes/Cocoa/AppKitOlderNote
s.html#NSMenu |
| 161 @"Contextual Menu Items/", |
| 162 |
| 163 // Input managers are deprecated, would only be loaded under specific |
| 164 // circumstances, and are entirely unavailable to 64-bit processes. |
| 165 // http://developer.apple.com/library/mac/releasenotes/Cocoa/AppKitOlderNote
s.html#NSInputManager |
| 166 @"Input Managers/", |
| 167 #endif // __LP64__ |
| 168 |
| 169 // Don't load third-party scripting additions either. |
| 170 @"ScriptingAdditions/" |
| 171 |
| 172 // This list is intentionally incomplete. For example, it doesn't block |
| 173 // printer drivers or Internet plug-ins. |
| 174 }; |
| 175 |
| 176 NSString* bundlePath = [self bundlePath]; |
| 177 NSUInteger bundlePathLength = [bundlePath length]; |
| 178 |
| 179 // Merge the prefix and suffix lists. |
| 180 for (NSString* blockedPrefix in blockedPrefixes) { |
| 181 for (size_t blockedSuffixIndex = 0; |
| 182 blockedSuffixIndex < arraysize(blockedSuffixes); |
| 183 ++blockedSuffixIndex) { |
| 184 NSString* blockedSuffix = blockedSuffixes[blockedSuffixIndex]; |
| 185 NSString* blockedPath = |
| 186 [blockedPrefix stringByAppendingPathComponent:blockedSuffix]; |
| 187 NSUInteger blockedPathLength = [blockedPath length]; |
| 188 |
| 189 // Do a case-insensitive comparison because most users will be on |
| 190 // case-insensitive HFS+ filesystems and it's cheaper than asking the |
| 191 // disk. This is like [bundlePath hasPrefix:blockedPath] but is |
| 192 // case-insensitive. |
| 193 if (bundlePathLength >= blockedPathLength && |
| 194 [bundlePath compare:blockedPath |
| 195 options:NSCaseInsensitiveSearch |
| 196 range:NSMakeRange(0, blockedPathLength)] == |
| 197 NSOrderedSame) { |
| 198 // If bundlePath is inside blockedPath (it has blockedPath as a |
| 199 // prefix), refuse to load it. |
| 200 return NO; |
| 201 } |
| 202 } |
142 } | 203 } |
143 | 204 |
144 return gOriginalNSBundleLoadIMP(self, _cmd) != nil; | 205 return gOriginalNSBundleLoadIMP(self, _cmd) != nil; |
145 } | 206 } |
146 @end | 207 @end |
147 | 208 |
148 namespace chrome_browser_application_mac { | 209 namespace chrome_browser_application_mac { |
149 | 210 |
150 // Maximum number of known named exceptions we'll support. There is | 211 // Maximum number of known named exceptions we'll support. There is |
151 // no central registration, but I only find about 75 possibilities in | 212 // no central registration, but I only find about 75 possibilities in |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 280 |
220 void SwizzleInit() { | 281 void SwizzleInit() { |
221 // Do-nothing wrapper so that we can arrange to only swizzle | 282 // Do-nothing wrapper so that we can arrange to only swizzle |
222 // -[NSException raise] when DCHECK() is turned on (as opposed to | 283 // -[NSException raise] when DCHECK() is turned on (as opposed to |
223 // replicating the preprocess logic which turns DCHECK() on). | 284 // replicating the preprocess logic which turns DCHECK() on). |
224 gOriginalInitIMP = ObjcEvilDoers::SwizzleImplementedInstanceMethods( | 285 gOriginalInitIMP = ObjcEvilDoers::SwizzleImplementedInstanceMethods( |
225 [NSException class], | 286 [NSException class], |
226 @selector(initWithName:reason:userInfo:), | 287 @selector(initWithName:reason:userInfo:), |
227 @selector(crInitWithName:reason:userInfo:)); | 288 @selector(crInitWithName:reason:userInfo:)); |
228 | 289 |
229 // Avoid loading broken input managers. | 290 // Avoid loading broken input managers and other parasitic plug-ins. |
230 gOriginalNSBundleLoadIMP = | 291 gOriginalNSBundleLoadIMP = |
231 ObjcEvilDoers::SwizzleImplementedInstanceMethods( | 292 ObjcEvilDoers::SwizzleImplementedInstanceMethods( |
232 [NSBundle class], | 293 [NSBundle class], |
233 @selector(load), | 294 @selector(load), |
234 @selector(crLoad)); | 295 @selector(crLoad)); |
235 } | 296 } |
236 | 297 |
237 } // namespace | 298 } // namespace |
238 | 299 |
239 @implementation BrowserCrApplication | 300 @implementation BrowserCrApplication |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 if (RenderViewHost* rvh = contents->render_view_host()) { | 521 if (RenderViewHost* rvh = contents->render_view_host()) { |
461 rvh->EnableRendererAccessibility(); | 522 rvh->EnableRendererAccessibility(); |
462 } | 523 } |
463 } | 524 } |
464 } | 525 } |
465 } | 526 } |
466 return [super accessibilitySetValue:value forAttribute:attribute]; | 527 return [super accessibilitySetValue:value forAttribute:attribute]; |
467 } | 528 } |
468 | 529 |
469 @end | 530 @end |
OLD | NEW |