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

Unified Diff: chrome/common/mac/cfbundle_blocker.mm

Issue 8226026: Allow whitelisted bundles to load in Chrome (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/mac/cfbundle_blocker.mm
===================================================================
--- chrome/common/mac/cfbundle_blocker.mm (revision 105162)
+++ chrome/common/mac/cfbundle_blocker.mm (working copy)
@@ -11,6 +11,7 @@
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsautorelease_pool.h"
+#import "base/memory/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
#include "third_party/mach_override/mach_override.h"
@@ -60,13 +61,6 @@
// Everything in the suffix list has a trailing slash so as to only block
// loading things contained in these directories.
NSString* const blocked_suffixes[] = {
- // SIMBL - http://code.google.com/p/simbl/source/browse/src/SIMBL.{h,m}.
- // It attempts to inject itself via an AppleScript event.
- // http://code.google.com/p/simbl/source/browse/SIMBL%20Agent/SIMBLAgent.m
- // Blocking input managers and scripting additions may already be enough
- // to prevent SIMBL plugins from loading.
- @"Application Support/SIMBL/Plugins/",
-
#if !defined(__LP64__)
// Contextual menu manager plug-ins are unavailable to 64-bit processes.
// http://developer.apple.com/library/mac/releasenotes/Cocoa/AppKitOlderNotes.html#NSMenu
@@ -146,12 +140,6 @@
return false;
}
-// Returns true if bundle_id identifies a bundle that is allowed to be loaded
-// even when found in a blocked directory.
-bool IsBundleIDAllowed(NSString* bundle_id) {
- return [bundle_id isEqualToString:@"com.google.osax.Google_Authenticator_BT"];
-}
-
typedef Boolean (*_CFBundleLoadExecutableAndReturnError_Type)(CFBundleRef,
Boolean,
CFErrorRef*);
@@ -169,44 +157,57 @@
DCHECK(g_original_underscore_cfbundle_load_executable_and_return_error);
base::mac::ScopedCFTypeRef<CFURLRef> url_cf(CFBundleCopyBundleURL(bundle));
- base::mac::ScopedCFTypeRef<CFStringRef> path_cf(
- CFURLCopyFileSystemPath(url_cf, kCFURLPOSIXPathStyle));
- NSString* path_ns = base::mac::CFToNSCast(path_cf);
+ scoped_nsobject<NSString> path(base::mac::CFToNSCast(
+ CFURLCopyFileSystemPath(url_cf, kCFURLPOSIXPathStyle)));
- CFStringRef identifier_cf = CFBundleGetIdentifier(bundle);
- NSString* identifier_ns = base::mac::CFToNSCast(identifier_cf);
+ NSString* bundle_id = base::mac::CFToNSCast(CFBundleGetIdentifier(bundle));
- if (IsBundlePathBlocked(path_ns) && !IsBundleIDAllowed(identifier_ns)) {
- NSString* identifier_ns_print = identifier_ns ? identifier_ns : @"(nil)";
+ NSDictionary* bundle_dictionary =
+ base::mac::CFToNSCast(CFBundleGetInfoDictionary(bundle));
+ NSString* version = [bundle_dictionary objectForKey:
+ base::mac::CFToNSCast(kCFBundleVersionKey)];
+ if (![version isKindOfClass:[NSString class]]) {
+ // Deal with pranksters.
+ version = nil;
+ }
+ if (IsBundlePathBlocked(path) && !IsBundleAllowed(bundle_id, version)) {
+ NSString* bundle_id_print = bundle_id ? bundle_id : @"(nil)";
+ NSString* version_print = version ? version : @"(nil)";
+
LOG(INFO) << "Blocking attempt to load bundle "
- << [identifier_ns_print UTF8String]
+ << [bundle_id_print UTF8String]
+ << " version "
+ << [version_print UTF8String]
<< " at "
- << [path_ns fileSystemRepresentation];
+ << [path fileSystemRepresentation];
Scott Hess - ex-Googler 2011/10/13 00:05:54 Wonder if this would be cleaner using -[NSString s
Mark Mentovai 2011/10/13 03:23:15 shess wrote:
if (error) {
- base::mac::ScopedCFTypeRef<CFStringRef> bundle_id(
+ base::mac::ScopedCFTypeRef<CFStringRef> app_bundle_id(
base::SysUTF8ToCFStringRef(base::mac::BaseBundleID()));
// 0xb10c10ad = "block load"
const CFIndex kBundleLoadBlocked = 0xb10c10ad;
NSMutableDictionary* error_dict =
- [NSMutableDictionary dictionaryWithCapacity:3];
- if (identifier_ns) {
- [error_dict setObject:identifier_ns forKey:@"identifier"];
+ [NSMutableDictionary dictionaryWithCapacity:4];
+ if (bundle_id) {
+ [error_dict setObject:bundle_id forKey:@"bundle_id"];
}
- if (path_ns) {
- [error_dict setObject:path_ns forKey:@"path"];
+ if (version) {
+ [error_dict setObject:version forKey:@"version"];
}
+ if (path) {
+ [error_dict setObject:path forKey:@"path"];
+ }
NSURL* url_ns = base::mac::CFToNSCast(url_cf);
- NSString* url_absolute_string_ns = [url_ns absoluteString];
- if (url_absolute_string_ns) {
- [error_dict setObject:url_absolute_string_ns forKey:@"url"];
+ NSString* url_absolute_string = [url_ns absoluteString];
+ if (url_absolute_string) {
+ [error_dict setObject:url_absolute_string forKey:@"url"];
}
*error = CFErrorCreate(NULL,
- bundle_id,
+ app_bundle_id,
kBundleLoadBlocked,
base::mac::NSToCFCast(error_dict));
}
@@ -233,6 +234,97 @@
}
}
+namespace {
+
+struct AllowedBundle {
+ // The bundle identifier to permit. These are matched with a case-sensitive
+ // literal comparison. "Children" of the declared bundle ID are permitted:
+ // if bundle_id here is @"org.chromium", it would match both @"org.chromium"
+ // and @"org.chromium.Chromium".
+ NSString* bundle_id;
+
+ // If bundle_id should only be permitted as of a certain minimum version,
+ // this string defines that version, which will be compared to the bundle's
+ // version with a numeric comparison. If bundle_id may be permitted at any
+ // version, set minimum_version to nil.
+ NSString* minimum_version;
+};
+
+} // namespace
+
+bool IsBundleAllowed(NSString* bundle_id, NSString* version) {
+ // The list of bundles that are allowed to load. Before adding an entry to
+ // this list, be sure that it's well-behaved. Specifically, anything that
+ // uses mach_override
+ // (https://github.com/rentzsch/mach_star/tree/master/mach_override) must
+ // use version 51ae3d199463fa84548f466d649f0821d579fdaf (July 22, 2011) or
+ // newer. Products added to the list must not cause crashes. Entries should
+ // include the name of the product, URL, and the name and e-mail address of
+ // someone responsible for the product's engineering. To add items to this
+ // list, file a bug at http://new.crbug.com/ using the "Defect on Mac OS"
+ // template, and provide the bundle ID (or IDs) and minimum CFBundleVersion
+ // that's safe for Chrome to load, along with the necessary product and
+ // contact information. Whitelisted bundles in this list may be removed if
+ // they are found to cause instability or otherwise behave badly. With
+ // proper contact information, Chrome developers may try to contact
+ // maintainers to resolve any problems.
+ const AllowedBundle kAllowedBundles[] = {
+ // Google Authenticator BT
+ // Dave MacLachlan <dmaclach@google.com>
+ { @"com.google.osax.Google_Authenticator_BT", nil },
+
+ // Default Folder X, http://www.stclairsoft.com/DefaultFolderX/
+ // Jon Gotow <gotow@stclairsoft.com>
+ { @"com.stclairsoft.DefaultFolderX", @"4.4.3" },
+
+ // MySpeed, http://www.enounce.com/myspeed
+ // Edward Bianchi <ejbianchi@enounce.com>
+ { @"com.enounce.MySpeed.osax", @"1201" },
+
+ // SIMBL (fork), https://github.com/albertz/simbl
+ // Albert Zeyer <albzey@googlemail.com>
+ { @"net.culater.SIMBL", nil },
+
+ // Smart Scroll, http://marcmoini.com/sx_en.html
+ // Marc Moini <marc@a9ff.com>
+ { @"com.marcmoini.SmartScroll", @"3.9" },
+ };
+
+ for (size_t index = 0; index < arraysize(kAllowedBundles); ++index) {
+ const AllowedBundle& allowed_bundle = kAllowedBundles[index];
+ NSString* allowed_bundle_id = allowed_bundle.bundle_id;
+ NSUInteger allowed_bundle_id_length = [allowed_bundle_id length];
+
+ // Permit bundle identifiers that are exactly equal to the allowed
+ // identifier, as well as "children" of the allowed identifier.
+ if ([bundle_id isEqualToString:allowed_bundle_id] ||
+ ([bundle_id length] > allowed_bundle_id_length &&
+ [bundle_id characterAtIndex:allowed_bundle_id_length] == '.' &&
+ [bundle_id hasPrefix:allowed_bundle_id])) {
+ NSString* minimum_version = allowed_bundle.minimum_version;
+ if (!minimum_version) {
+ // If the rule didn't declare any version requirement, the bundle is
+ // allowed to load.
+ return true;
+ }
+
+ if (!version) {
+ // If there wasn't any version but one was required, the bundle isn't
+ // allowed to load.
+ return false;
+ }
+
+ // A numeric search is appropriate for comparing version numbers.
+ NSComparisonResult result = [version compare:minimum_version
+ options:NSNumericSearch];
+ return result != NSOrderedAscending;
+ }
+ }
+
+ // Nothing matched.
+ return false;
+}
+
} // namespace mac
} // namespace common
} // namespace chrome

Powered by Google App Engine
This is Rietveld 408576698