From d4310ac944e5f3063bb23558ba25ccf76fec0968 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 16 Mar 2010 22:55:08 -0700 Subject: [PATCH] Rework permissions to be retained when an app is temporarily uninstalled. This allows us to keep the assigned permissions when apps are temporarily removed due to the SD card being unmounted, and also if you use the facility to uninstall an app but keep its data. Also fixes issue #2515189: Potential permission spoofing attack in Android (external bug 7166) Change-Id: I2a120ec938552028c989f9e0e890c32773957738 --- .../com/android/server/IntentResolver.java | 72 ++- .../android/server/PackageManagerService.java | 474 +++++++++++++----- .../server/am/ActivityManagerService.java | 4 +- tests/AndroidTests/Android.mk | 4 +- .../apks/install_decl_perm/Android.mk | 11 + .../install_decl_perm/AndroidManifest.xml | 21 + .../install_decl_perm/res/values/strings.xml | 5 + .../apks/install_use_perm_good/Android.mk | 11 + .../install_use_perm_good/AndroidManifest.xml | 10 + .../res/values/strings.xml | 5 + tests/AndroidTests/res/raw/install_decl_perm | Bin 0 -> 2646 bytes .../res/raw/install_use_perm_good | Bin 0 -> 2480 bytes .../unit_tests/PackageManagerTests.java | 265 ++++++++++ 13 files changed, 743 insertions(+), 139 deletions(-) create mode 100644 tests/AndroidTests/apks/install_decl_perm/Android.mk create mode 100644 tests/AndroidTests/apks/install_decl_perm/AndroidManifest.xml create mode 100644 tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml create mode 100644 tests/AndroidTests/apks/install_use_perm_good/Android.mk create mode 100644 tests/AndroidTests/apks/install_use_perm_good/AndroidManifest.xml create mode 100644 tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml create mode 100644 tests/AndroidTests/res/raw/install_decl_perm create mode 100644 tests/AndroidTests/res/raw/install_use_perm_good diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java index 19b0a769bbc35..8ab65e927bb6f 100644 --- a/services/java/com/android/server/IntentResolver.java +++ b/services/java/com/android/server/IntentResolver.java @@ -91,38 +91,64 @@ public class IntentResolver { } } - void dumpMap(PrintWriter out, String prefix, Map> map) { + boolean dumpMap(PrintWriter out, String titlePrefix, String title, + String prefix, Map> map, String packageName) { String eprefix = prefix + " "; String fprefix = prefix + " "; + boolean printedSomething = false; for (Map.Entry> e : map.entrySet()) { - out.print(eprefix); out.print(e.getKey()); out.println(":"); ArrayList a = e.getValue(); final int N = a.size(); + boolean printedHeader = false; for (int i=0; i { @@ -286,6 +312,10 @@ public class IntentResolver { return true; } + protected String packageForFilter(F filter) { + return null; + } + protected R newResult(F filter, int match) { return (R)filter; } diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 55725bdab7632..87a744e69cac4 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -29,7 +29,6 @@ import org.xmlpull.v1.XmlSerializer; import android.app.ActivityManagerNative; import android.app.IActivityManager; -import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.app.backup.IBackupManager; import android.content.ComponentName; @@ -79,14 +78,11 @@ import android.os.Environment; import android.os.FileObserver; import android.os.FileUtils; import android.os.Handler; -import android.os.StatFs; -import android.os.storage.StorageResultCode; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; -import android.provider.Settings; import android.security.SystemKeyStore; import android.util.*; import android.view.Display; @@ -122,6 +118,17 @@ import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; +/** + * Keep track of all those .apks everywhere. + * + * This is very central to the platform's security; please run the unit + * tests whenever making modifications here: + * +mmm frameworks/base/tests/AndroidTests +adb install -r -f out/target/product/passion/data/app/AndroidTests.apk +adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner + * + */ class PackageManagerService extends IPackageManager.Stub { private static final String TAG = "PackageManager"; private static final boolean DEBUG_SETTINGS = false; @@ -912,7 +919,7 @@ class PackageManagerService extends IPackageManager.Stub { + ((SystemClock.uptimeMillis()-startTime)/1000f) + " seconds"); - updatePermissionsLP(); + updatePermissionsLP(null, null, true, false); mSettings.writeLP(); @@ -1207,6 +1214,36 @@ class PackageManagerService extends IPackageManager.Stub { return cur; } + static int[] removeInt(int[] cur, int val) { + if (cur == null) { + return null; + } + final int N = cur.length; + for (int i=0; i 0) { + System.arraycopy(cur, 0, ret, 0, i); + } + if (i < (N-1)) { + System.arraycopy(cur, i, ret, i+1, N-i-1); + } + return ret; + } + } + return cur; + } + + static int[] removeInts(int[] cur, int[] rem) { + if (rem == null) return cur; + if (cur == null) return cur; + final int N = rem.length; + for (int i=0; i out = new ArrayList(10); for (BasePermission p : mSettings.mPermissions.values()) { if (group == null) { - if (p.perm.info.group == null) { - out.add(PackageParser.generatePermissionInfo(p.perm, flags)); + if (p.perm == null || p.perm.info.group == null) { + out.add(generatePermissionInfo(p, flags)); } } else { - if (group.equals(p.perm.info.group)) { + if (p.perm != null && group.equals(p.perm.info.group)) { out.add(PackageParser.generatePermissionInfo(p.perm, flags)); } } @@ -1600,6 +1650,7 @@ class PackageManagerService extends IPackageManager.Stub { "Not allowed to modify non-dynamic permission " + info.name); } + bp.protectionLevel = info.protectionLevel; bp.perm = new PackageParser.Permission(tree.perm.owner, new PermissionInfo(info)); bp.perm.info.packageName = tree.perm.info.packageName; @@ -3268,6 +3319,7 @@ class PackageManagerService extends IPackageManager.Stub { BasePermission tree = findPermissionTreeLP(p.info.name); if (tree == null || tree.sourcePackage.equals(p.info.packageName)) { + bp.packageSetting = pkgSetting; bp.perm = p; bp.uid = pkg.applicationInfo.uid; if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { @@ -3298,6 +3350,9 @@ class PackageManagerService extends IPackageManager.Stub { r.append("DUP:"); r.append(p.info.name); } + if (bp.perm == p) { + bp.protectionLevel = p.info.protectionLevel; + } } else { Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: no group " @@ -3723,15 +3778,7 @@ class PackageManagerService extends IPackageManager.Stub { bp = mSettings.mPermissionTrees.get(p.info.name); } if (bp != null && bp.perm == p) { - if (bp.type != BasePermission.TYPE_BUILTIN) { - if (tree) { - mSettings.mPermissionTrees.remove(p.info.name); - } else { - mSettings.mPermissions.remove(p.info.name); - } - } else { - bp.perm = null; - } + bp.perm = null; if (chatty) { if (r == null) { r = new StringBuilder(256); @@ -3770,16 +3817,38 @@ class PackageManagerService extends IPackageManager.Stub { return name != null && name.endsWith(".apk"); } - private void updatePermissionsLP() { + private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { + for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { + if (pkgInfo.permissions.get(i).info.name.equals(perm)) { + return true; + } + } + return false; + } + + private void updatePermissionsLP(String changingPkg, + PackageParser.Package pkgInfo, boolean grantPermissions, boolean replace) { // Make sure there are no dangling permission trees. Iterator it = mSettings.mPermissionTrees .values().iterator(); while (it.hasNext()) { BasePermission bp = it.next(); - if (bp.perm == null) { + if (bp.packageSetting == null) { + // We may not yet have parsed the package, so just see if + // we still know about its settings. + bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); + } + if (bp.packageSetting == null) { Slog.w(TAG, "Removing dangling permission tree: " + bp.name + " from package " + bp.sourcePackage); it.remove(); + } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { + if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { + Slog.i(TAG, "Removing old permission tree: " + bp.name + + " from package " + bp.sourcePackage); + grantPermissions = true; + it.remove(); + } } } @@ -3792,9 +3861,10 @@ class PackageManagerService extends IPackageManager.Stub { if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" + bp.name + " pkg=" + bp.sourcePackage + " info=" + bp.pendingInfo); - if (bp.perm == null && bp.pendingInfo != null) { + if (bp.packageSetting == null && bp.pendingInfo != null) { BasePermission tree = findPermissionTreeLP(bp.name); if (tree != null) { + bp.packageSetting = tree.packageSetting; bp.perm = new PackageParser.Permission(tree.perm.owner, new PermissionInfo(bp.pendingInfo)); bp.perm.info.packageName = tree.perm.info.packageName; @@ -3803,17 +3873,37 @@ class PackageManagerService extends IPackageManager.Stub { } } } - if (bp.perm == null) { + if (bp.packageSetting == null) { + // We may not yet have parsed the package, so just see if + // we still know about its settings. + bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); + } + if (bp.packageSetting == null) { Slog.w(TAG, "Removing dangling permission: " + bp.name + " from package " + bp.sourcePackage); it.remove(); + } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { + if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { + Slog.i(TAG, "Removing old permission: " + bp.name + + " from package " + bp.sourcePackage); + grantPermissions = true; + it.remove(); + } } } // Now update the permissions for all packages, in particular // replace the granted permissions of the system packages. - for (PackageParser.Package pkg : mPackages.values()) { - grantPermissionsLP(pkg, false); + if (grantPermissions) { + for (PackageParser.Package pkg : mPackages.values()) { + if (pkg != pkgInfo) { + grantPermissionsLP(pkg, false); + } + } + } + + if (pkgInfo != null) { + grantPermissionsLP(pkgInfo, replace); } } @@ -3823,7 +3913,7 @@ class PackageManagerService extends IPackageManager.Stub { return; } final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; - boolean addedPermission = false; + boolean changedPermission = false; if (replace) { ps.permissionsFixed = false; @@ -3841,26 +3931,26 @@ class PackageManagerService extends IPackageManager.Stub { for (int i=0; i(gp.grantedPermissions); } } - + private final class ActivityIntentResolver extends IntentResolver { public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) { @@ -4029,6 +4132,11 @@ class PackageManagerService extends IPackageManager.Stub { return true; } + @Override + protected String packageForFilter(PackageParser.ActivityIntentInfo info) { + return info.activity.owner.packageName; + } + @Override protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, int match) { @@ -4069,7 +4177,9 @@ class PackageManagerService extends IPackageManager.Stub { out.print(prefix); out.print( Integer.toHexString(System.identityHashCode(filter.activity))); out.print(' '); - out.println(filter.activity.getComponentShortName()); + out.print(filter.activity.getComponentShortName()); + out.print(" filter "); + out.println(Integer.toHexString(System.identityHashCode(filter))); } // List filterEnabled(List resolveInfoList) { @@ -4179,6 +4289,11 @@ class PackageManagerService extends IPackageManager.Stub { return true; } + @Override + protected String packageForFilter(PackageParser.ServiceIntentInfo info) { + return info.service.owner.packageName; + } + @Override protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, int match) { @@ -4220,7 +4335,9 @@ class PackageManagerService extends IPackageManager.Stub { out.print(prefix); out.print( Integer.toHexString(System.identityHashCode(filter.service))); out.print(' '); - out.println(filter.service.getComponentShortName()); + out.print(filter.service.getComponentShortName()); + out.print(" filter "); + out.println(Integer.toHexString(System.identityHashCode(filter))); } // List filterEnabled(List resolveInfoList) { @@ -4389,7 +4506,8 @@ class PackageManagerService extends IPackageManager.Stub { SCAN_MONITOR | SCAN_NO_PATHS); if (p != null) { synchronized (mPackages) { - grantPermissionsLP(p, false); + updatePermissionsLP(p.packageName, p, + p.permissions.size() > 0, false); } addedPackage = p.applicationInfo.packageName; addedUid = p.applicationInfo.uid; @@ -5410,7 +5528,8 @@ class PackageManagerService extends IPackageManager.Stub { parseFlags |= ~PackageManager.INSTALL_REPLACE_EXISTING; scanPackageLI(restoreFile, parseFlags, scanMode); synchronized (mPackages) { - grantPermissionsLP(deletedPackage, false); + updatePermissionsLP(deletedPackage.packageName, deletedPackage, + true, false); mSettings.writeLP(); } if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) { @@ -5536,7 +5655,8 @@ class PackageManagerService extends IPackageManager.Stub { Log.d(TAG, "New package installed in " + newPackage.mPath); } synchronized (mPackages) { - grantPermissionsLP(newPackage, true); + updatePermissionsLP(newPackage.packageName, newPackage, + newPackage.permissions.size() > 0, true); res.name = pkgName; res.uid = newPackage.applicationInfo.uid; res.pkg = newPackage; @@ -5917,19 +6037,23 @@ class PackageManagerService extends IPackageManager.Stub { File dataDir = new File(pkg.applicationInfo.dataDir); dataDir.delete(); } - schedulePackageCleaning(packageName); - synchronized (mPackages) { - if (outInfo != null) { - outInfo.removedUid = mSettings.removePackageLP(packageName); - } - } } synchronized (mPackages) { - if ( (deletedPs != null) && (deletedPs.sharedUser != null)) { - // remove permissions associated with package - mSettings.updateSharedUserPermsLP(deletedPs, mGlobalGids); - } if (deletedPs != null) { + schedulePackageCleaning(packageName); + + if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { + if (outInfo != null) { + outInfo.removedUid = mSettings.removePackageLP(packageName); + } + if (deletedPs != null) { + updatePermissionsLP(deletedPs.name, null, false, false); + if (deletedPs.sharedUser != null) { + // remove permissions associated with package + mSettings.updateSharedUserPermsLP(deletedPs, mGlobalGids); + } + } + } // remove from preferred activities. ArrayList removed = new ArrayList(); for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) { @@ -6003,7 +6127,7 @@ class PackageManagerService extends IPackageManager.Stub { return false; } synchronized (mPackages) { - grantPermissionsLP(newPkg, true); + updatePermissionsLP(newPkg.packageName, newPkg, true, true); mSettings.writeLP(); } return true; @@ -6659,35 +6783,102 @@ class PackageManagerService extends IPackageManager.Stub { return; } + String packageName = null; + + int opti = 0; + while (opti < args.length) { + String opt = args[opti]; + if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { + break; + } + opti++; + if ("-a".equals(opt)) { + // Right now we only know how to print all. + } else if ("-h".equals(opt)) { + pw.println("Package manager dump options:"); + pw.println(" [-h] [cmd] ..."); + pw.println(" cmd may be one of:"); + pw.println(" [package.name]: info about given package"); + return; + } else { + pw.println("Unknown argument: " + opt + "; use -h for help"); + } + } + + // Is the caller requesting to dump a particular piece of data? + if (opti < args.length) { + String cmd = args[opti]; + opti++; + // Is this a package name? + if ("android".equals(cmd) || cmd.contains(".")) { + packageName = cmd; + } + } + + boolean printedTitle = false; + synchronized (mPackages) { - pw.println("Activity Resolver Table:"); - mActivities.dump(pw, " "); - pw.println(" "); - pw.println("Receiver Resolver Table:"); - mReceivers.dump(pw, " "); - pw.println(" "); - pw.println("Service Resolver Table:"); - mServices.dump(pw, " "); - pw.println(" "); - pw.println("Preferred Activities:"); - mSettings.mPreferredActivities.dump(pw, " "); - pw.println(" "); - pw.println("Permissions:"); + if (mActivities.dump(pw, "Activity Resolver Table:", " ", packageName)) { + printedTitle = true; + } + if (mReceivers.dump(pw, printedTitle + ? "\nReceiver Resolver Table:" : "Receiver Resolver Table:", + " ", packageName)) { + printedTitle = true; + } + if (mServices.dump(pw, printedTitle + ? "\nService Resolver Table:" : "Service Resolver Table:", + " ", packageName)) { + printedTitle = true; + } + if (mSettings.mPreferredActivities.dump(pw, printedTitle + ? "\nPreferred Activities:" : "Preferred Activities:", + " ", packageName)) { + printedTitle = true; + } + boolean printedSomething = false; { for (BasePermission p : mSettings.mPermissions.values()) { + if (packageName != null && !packageName.equals(p.sourcePackage)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Permissions:"); + printedSomething = true; + printedTitle = true; + } pw.print(" Permission ["); pw.print(p.name); pw.print("] ("); pw.print(Integer.toHexString(System.identityHashCode(p))); pw.println("):"); pw.print(" sourcePackage="); pw.println(p.sourcePackage); pw.print(" uid="); pw.print(p.uid); pw.print(" gids="); pw.print(arrayToString(p.gids)); - pw.print(" type="); pw.println(p.type); + pw.print(" type="); pw.print(p.type); + pw.print(" prot="); pw.println(p.protectionLevel); + if (p.packageSetting != null) { + pw.print(" packageSetting="); pw.println(p.packageSetting); + } + if (p.perm != null) { + pw.print(" perm="); pw.println(p.perm); + } } } - pw.println(" "); - pw.println("Packages:"); + printedSomething = false; + SharedUserSetting packageSharedUser = null; { for (PackageSetting ps : mSettings.mPackages.values()) { + if (packageName != null && !packageName.equals(ps.realName) + && !packageName.equals(ps.name)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Packages:"); + printedSomething = true; + printedTitle = true; + } + packageSharedUser = ps.sharedUser; pw.print(" Package ["); pw.print(ps.realName != null ? ps.realName : ps.name); pw.print("] ("); @@ -6771,20 +6962,38 @@ class PackageManagerService extends IPackageManager.Stub { } } } + printedSomething = false; if (mSettings.mRenamedPackages.size() > 0) { - pw.println(" "); - pw.println("Renamed packages:"); for (HashMap.Entry e : mSettings.mRenamedPackages.entrySet()) { + if (packageName != null && !packageName.equals(e.getKey()) + && !packageName.equals(e.getValue())) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Renamed packages:"); + printedSomething = true; + printedTitle = true; + } pw.print(" "); pw.print(e.getKey()); pw.print(" -> "); pw.println(e.getValue()); } } + printedSomething = false; if (mSettings.mDisabledSysPackages.size() > 0) { - pw.println(" "); - pw.println("Hidden system packages:"); for (PackageSetting ps : mSettings.mDisabledSysPackages.values()) { - pw.print(" Package ["); + if (packageName != null && !packageName.equals(ps.realName) + && !packageName.equals(ps.name)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Hidden system packages:"); + printedSomething = true; + printedTitle = true; + } + pw.print(" Package ["); pw.print(ps.realName != null ? ps.realName : ps.name); pw.print("] ("); pw.print(Integer.toHexString(System.identityHashCode(ps))); @@ -6798,10 +7007,18 @@ class PackageManagerService extends IPackageManager.Stub { pw.print(" resourcePath="); pw.println(ps.resourcePathString); } } - pw.println(" "); - pw.println("Shared Users:"); + printedSomething = false; { for (SharedUserSetting su : mSettings.mSharedUsers.values()) { + if (packageName != null && su != packageSharedUser) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Shared users:"); + printedSomething = true; + printedTitle = true; + } pw.print(" SharedUser ["); pw.print(su.name); pw.print("] ("); pw.print(Integer.toHexString(System.identityHashCode(su))); pw.println("):"); @@ -6818,29 +7035,40 @@ class PackageManagerService extends IPackageManager.Stub { } } - pw.println(" "); - pw.println("Settings parse messages:"); - pw.println(mSettings.mReadMessages.toString()); - - pw.println(" "); - pw.println("Package warning messages:"); - File fname = getSettingsProblemFile(); - FileInputStream in; - try { - in = new FileInputStream(fname); - int avail = in.available(); - byte[] data = new byte[avail]; - in.read(data); - pw.println(new String(data)); - } catch (FileNotFoundException e) { - } catch (IOException e) { + if (packageName == null) { + if (printedTitle) pw.println(" "); + printedTitle = true; + pw.println("Settings parse messages:"); + pw.println(mSettings.mReadMessages.toString()); + + pw.println(" "); + pw.println("Package warning messages:"); + File fname = getSettingsProblemFile(); + FileInputStream in; + try { + in = new FileInputStream(fname); + int avail = in.available(); + byte[] data = new byte[avail]; + in.read(data); + pw.println(new String(data)); + } catch (FileNotFoundException e) { + } catch (IOException e) { + } } } synchronized (mProviders) { - pw.println(" "); - pw.println("Registered ContentProviders:"); + boolean printedSomething = false; for (PackageParser.Provider p : mProviders.values()) { + if (packageName != null && !packageName.equals(p.info.packageName)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Registered ContentProviders:"); + printedSomething = true; + printedTitle = true; + } pw.print(" ["); pw.print(p.info.authority); pw.print("]: "); pw.println(p.toString()); } @@ -6854,7 +7082,9 @@ class PackageManagerService extends IPackageManager.Stub { final String name; String sourcePackage; + PackageSettingBase packageSetting; final int type; + int protectionLevel; PackageParser.Permission perm; PermissionInfo pendingInfo; int uid; @@ -6864,6 +7094,14 @@ class PackageManagerService extends IPackageManager.Stub { name = _name; sourcePackage = _sourcePackage; type = _type; + // Default to most conservative protection level. + protectionLevel = PermissionInfo.PROTECTION_SIGNATURE; + } + + public String toString() { + return "BasePermission{" + + Integer.toHexString(System.identityHashCode(this)) + + " " + name + "}"; } } @@ -7496,6 +7734,10 @@ class PackageManagerService extends IPackageManager.Stub { private final IntentResolver mPreferredActivities = new IntentResolver() { @Override + protected String packageForFilter(PreferredActivity filter) { + return filter.mActivity.getPackageName(); + } + @Override protected void dumpFilter(PrintWriter out, String prefix, PreferredActivity filter) { out.print(prefix); out.print( @@ -7734,9 +7976,10 @@ class PackageManagerService extends IPackageManager.Stub { + " from pkg " + bp.sourcePackage + " to " + newPkg); bp.sourcePackage = newPkg; + bp.packageSetting = null; bp.perm = null; if (bp.pendingInfo != null) { - bp.sourcePackage = newPkg; + bp.pendingInfo.packageName = newPkg; } bp.uid = 0; bp.gids = null; @@ -8243,7 +8486,7 @@ class PackageManagerService extends IPackageManager.Stub { // be set. for (final String name : pkg.grantedPermissions) { BasePermission bp = mPermissions.get(name); - if ((bp != null) && (bp.perm != null) && (bp.perm.info != null)) { + if (bp != null) { // We only need to write signature or system permissions but this wont // match the semantics of grantedPermissions. So write all permissions. serializer.startTag(null, "item"); @@ -8337,6 +8580,11 @@ class PackageManagerService extends IPackageManager.Stub { serializer.startTag(null, "item"); serializer.attribute(null, "name", bp.name); serializer.attribute(null, "package", bp.sourcePackage); + if (bp.protectionLevel != + PermissionInfo.PROTECTION_NORMAL) { + serializer.attribute(null, "protection", + Integer.toString(bp.protectionLevel)); + } if (DEBUG_SETTINGS) Log.v(TAG, "Writing perm: name=" + bp.name + " type=" + bp.type); if (bp.type == BasePermission.TYPE_DYNAMIC) { @@ -8352,11 +8600,6 @@ class PackageManagerService extends IPackageManager.Stub { serializer.attribute(null, "label", pi.nonLocalizedLabel.toString()); } - if (pi.protectionLevel != - PermissionInfo.PROTECTION_NORMAL) { - serializer.attribute(null, "protection", - Integer.toString(pi.protectionLevel)); - } } } serializer.endTag(null, "item"); @@ -8558,6 +8801,8 @@ class PackageManagerService extends IPackageManager.Stub { dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL); + bp.protectionLevel = readInt(parser, null, "protection", + PermissionInfo.PROTECTION_NORMAL); if (dynamic) { PermissionInfo pi = new PermissionInfo(); pi.packageName = sourcePackage.intern(); @@ -8565,8 +8810,7 @@ class PackageManagerService extends IPackageManager.Stub { pi.icon = readInt(parser, null, "icon", 0); pi.nonLocalizedLabel = parser.getAttributeValue( null, "label"); - pi.protectionLevel = readInt(parser, null, "protection", - PermissionInfo.PROTECTION_NORMAL); + pi.protectionLevel = bp.protectionLevel; bp.pendingInfo = pi; } out.put(bp.name, bp); @@ -9322,10 +9566,6 @@ class PackageManagerService extends IPackageManager.Stub { // Scan the package if (scanPackageLI(pkg, parseFlags, SCAN_MONITOR) != null) { synchronized (mPackages) { - // Grant permissions - grantPermissionsLP(pkg, false); - // Persist settings - mSettings.writeLP(); retCode = PackageManager.INSTALL_SUCCEEDED; pkgList.add(pkg.packageName); // Post process args @@ -9344,6 +9584,10 @@ class PackageManagerService extends IPackageManager.Stub { } } } + synchronized (mPackages) { + // Persist settings + mSettings.writeLP(); + } // Send a broadcast to let everyone know we are done processing if (sendUpdateBroadcast) { sendResourcesChangedBroadcast(true, pkgList, uidArr); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index a437d9582af5c..2ecebed86f248 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -9356,7 +9356,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen dumpAll = true; } else if ("-h".equals(opt)) { pw.println("Activity manager dump options:"); - pw.println(" [-a] [h- [cmd] ..."); + pw.println(" [-a] [-h] [cmd] ..."); pw.println(" cmd may be one of:"); pw.println(" activities: activity stack state"); pw.println(" broadcasts: broadcast state"); @@ -9756,7 +9756,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen pw.println(" "); pw.println("Receiver Resolver Table:"); - mReceiverResolver.dump(pw, " "); + mReceiverResolver.dump(pw, null, " ", null); needSep = true; } diff --git a/tests/AndroidTests/Android.mk b/tests/AndroidTests/Android.mk index 0d29c358afdeb..c22547feaf5bd 100644 --- a/tests/AndroidTests/Android.mk +++ b/tests/AndroidTests/Android.mk @@ -16,4 +16,6 @@ LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) -include $(call all-makefiles-under,$(LOCAL_PATH)) +LOCAL_STORED_PATH:= $(LOCAL_PATH) +include $(call all-makefiles-under,$(LOCAL_STORED_PATH)) +include $(call all-makefiles-under,$(LOCAL_STORED_PATH)/apks) diff --git a/tests/AndroidTests/apks/install_decl_perm/Android.mk b/tests/AndroidTests/apks/install_decl_perm/Android.mk new file mode 100644 index 0000000000000..9dcf9a0f0a149 --- /dev/null +++ b/tests/AndroidTests/apks/install_decl_perm/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := AndroidTests_install_decl_perm + +include $(BUILD_PACKAGE) + diff --git a/tests/AndroidTests/apks/install_decl_perm/AndroidManifest.xml b/tests/AndroidTests/apks/install_decl_perm/AndroidManifest.xml new file mode 100644 index 0000000000000..43875007c89f8 --- /dev/null +++ b/tests/AndroidTests/apks/install_decl_perm/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml b/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml new file mode 100644 index 0000000000000..5564300690b20 --- /dev/null +++ b/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/AndroidTests/apks/install_use_perm_good/Android.mk b/tests/AndroidTests/apks/install_use_perm_good/Android.mk new file mode 100644 index 0000000000000..a25a03c759644 --- /dev/null +++ b/tests/AndroidTests/apks/install_use_perm_good/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := AndroidTests_install_use_perm_good + +include $(BUILD_PACKAGE) + diff --git a/tests/AndroidTests/apks/install_use_perm_good/AndroidManifest.xml b/tests/AndroidTests/apks/install_use_perm_good/AndroidManifest.xml new file mode 100644 index 0000000000000..6dd3e7113d4da --- /dev/null +++ b/tests/AndroidTests/apks/install_use_perm_good/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml b/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml new file mode 100644 index 0000000000000..5564300690b20 --- /dev/null +++ b/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/AndroidTests/res/raw/install_decl_perm b/tests/AndroidTests/res/raw/install_decl_perm new file mode 100644 index 0000000000000000000000000000000000000000..6f223213e2416fe3b252f52780d45f5c4cc732e2 GIT binary patch literal 2646 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