Skip to content

Commit cd23823

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Fix issue # 3227963: SecurityException: Neither user 10023 nor..." into gingerbread
2 parents 9b447d1 + 690d20b commit cd23823

File tree

2 files changed

+118
-33
lines changed

2 files changed

+118
-33
lines changed

cmds/pm/src/com/android/commands/pm/Pm.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818

1919
import com.android.internal.content.PackageHelper;
2020

21+
import android.app.ActivityManagerNative;
2122
import android.content.ComponentName;
2223
import android.content.pm.ApplicationInfo;
2324
import android.content.pm.FeatureInfo;
25+
import android.content.pm.IPackageDataObserver;
2426
import android.content.pm.IPackageDeleteObserver;
2527
import android.content.pm.IPackageInstallObserver;
2628
import android.content.pm.IPackageManager;
@@ -100,6 +102,11 @@ public void run(String[] args) {
100102
return;
101103
}
102104

105+
if ("clear".equals(op)) {
106+
runClear();
107+
return;
108+
}
109+
103110
if ("enable".equals(op)) {
104111
runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
105112
return;
@@ -809,6 +816,55 @@ private boolean deletePackage(String pkg, int unInstallFlags) {
809816
return obs.result;
810817
}
811818

819+
class ClearDataObserver extends IPackageDataObserver.Stub {
820+
boolean finished;
821+
boolean result;
822+
823+
@Override
824+
public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
825+
synchronized (this) {
826+
finished = true;
827+
result = succeeded;
828+
notifyAll();
829+
}
830+
}
831+
832+
}
833+
834+
private void runClear() {
835+
String pkg = nextArg();
836+
if (pkg == null) {
837+
System.err.println("Error: no package specified");
838+
showUsage();
839+
return;
840+
}
841+
842+
ClearDataObserver obs = new ClearDataObserver();
843+
try {
844+
if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs)) {
845+
System.err.println("Failed");
846+
}
847+
848+
synchronized (obs) {
849+
while (!obs.finished) {
850+
try {
851+
obs.wait();
852+
} catch (InterruptedException e) {
853+
}
854+
}
855+
}
856+
857+
if (obs.result) {
858+
System.err.println("Success");
859+
} else {
860+
System.err.println("Failed");
861+
}
862+
} catch (RemoteException e) {
863+
System.err.println(e.toString());
864+
System.err.println(PM_NOT_RUNNING_ERR);
865+
}
866+
}
867+
812868
private static String enabledSettingToString(int state) {
813869
switch (state) {
814870
case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
@@ -944,6 +1000,7 @@ private static void showUsage() {
9441000
System.err.println(" pm path PACKAGE");
9451001
System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
9461002
System.err.println(" pm uninstall [-k] PACKAGE");
1003+
System.err.println(" pm clear PACKAGE");
9471004
System.err.println(" pm enable PACKAGE_OR_COMPONENT");
9481005
System.err.println(" pm disable PACKAGE_OR_COMPONENT");
9491006
System.err.println(" pm setInstallLocation [0/auto] [1/internal] [2/external]");
@@ -986,6 +1043,8 @@ private static void showUsage() {
9861043
System.err.println(" -k: keep the data and cache directories around.");
9871044
System.err.println("after the package removal.");
9881045
System.err.println("");
1046+
System.err.println("The clear command deletes all data associated with a package.");
1047+
System.err.println("");
9891048
System.err.println("The enable and disable commands change the enabled state of");
9901049
System.err.println("a given package or component (written as \"package/class\").");
9911050
System.err.println("");

services/java/com/android/server/PackageManagerService.java

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3663,17 +3663,6 @@ void removePackageLI(PackageParser.Package pkg, boolean chatty) {
36633663
mAppDirs.remove(pkg.mPath);
36643664
}
36653665

3666-
PackageSetting ps = (PackageSetting)pkg.mExtras;
3667-
if (ps != null && ps.sharedUser != null) {
3668-
// XXX don't do this until the data is removed.
3669-
if (false) {
3670-
ps.sharedUser.packages.remove(ps);
3671-
if (ps.sharedUser.packages.size() == 0) {
3672-
// Remove.
3673-
}
3674-
}
3675-
}
3676-
36773666
int N = pkg.providers.size();
36783667
StringBuilder r = null;
36793668
int i;
@@ -5695,12 +5684,26 @@ private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
56955684
return;
56965685
}
56975686
}
5687+
5688+
killApplication(packageName, oldPkg.applicationInfo.uid);
5689+
56985690
res.removedInfo.uid = oldPkg.applicationInfo.uid;
56995691
res.removedInfo.removedPackage = packageName;
57005692
// Remove existing system package
57015693
removePackageLI(oldPkg, true);
57025694
synchronized (mPackages) {
5703-
mSettings.disableSystemPackageLP(packageName);
5695+
if (!mSettings.disableSystemPackageLP(packageName) && deletedPackage != null) {
5696+
// We didn't need to disable the .apk as a current system package,
5697+
// which means we are replacing another update that is already
5698+
// installed. We need to make sure to delete the older one's .apk.
5699+
res.removedInfo.args = createInstallArgs(isExternal(pkg)
5700+
? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL,
5701+
deletedPackage.applicationInfo.sourceDir,
5702+
deletedPackage.applicationInfo.publicSourceDir,
5703+
deletedPackage.applicationInfo.nativeLibraryDir);
5704+
} else {
5705+
res.removedInfo.args = null;
5706+
}
57045707
}
57055708

57065709
// Successfully disabled the old package. Now proceed with re-installation
@@ -5739,17 +5742,6 @@ private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
57395742
}
57405743
mSettings.writeLP();
57415744
}
5742-
} else {
5743-
// If this is an update to an existing update, setup
5744-
// to remove the existing update.
5745-
synchronized (mPackages) {
5746-
PackageSetting ps = mSettings.getDisabledSystemPkg(packageName);
5747-
if (ps != null && ps.codePathString != null &&
5748-
!ps.codePathString.equals(oldPkgSetting.codePathString)) {
5749-
res.removedInfo.args = createInstallArgs(0, oldPkgSetting.codePathString,
5750-
oldPkgSetting.resourcePathString, oldPkgSetting.nativeLibraryPathString);
5751-
}
5752-
}
57535745
}
57545746
}
57555747

@@ -6252,24 +6244,21 @@ private boolean deleteSystemPackageLI(PackageParser.Package p,
62526244
ps = mSettings.getDisabledSystemPkg(p.packageName);
62536245
}
62546246
if (ps == null) {
6255-
Slog.w(TAG, "Attempt to delete system package "+ p.packageName);
6247+
Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName);
62566248
return false;
62576249
} else {
62586250
Log.i(TAG, "Deleting system pkg from data partition");
62596251
}
62606252
// Delete the updated package
62616253
outInfo.isRemovedPackageSystemUpdate = true;
6262-
final boolean deleteCodeAndResources;
62636254
if (ps.versionCode < p.mVersionCode) {
6264-
// Delete code and resources for downgrades
6265-
deleteCodeAndResources = true;
6255+
// Delete data for downgrades
62666256
flags &= ~PackageManager.DONT_DELETE_DATA;
62676257
} else {
62686258
// Preserve data by setting flag
6269-
deleteCodeAndResources = false;
62706259
flags |= PackageManager.DONT_DELETE_DATA;
62716260
}
6272-
boolean ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo,
6261+
boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo,
62736262
writeSettings);
62746263
if (!ret) {
62756264
return false;
@@ -7850,6 +7839,12 @@ static final class PackageSetting extends PackageSettingBase {
78507839
pkgFlags);
78517840
}
78527841

7842+
PackageSetting(PackageSetting orig) {
7843+
super(orig.name, orig.realName, orig.codePath, orig.resourcePath,
7844+
orig.nativeLibraryPathString, orig.versionCode, orig.pkgFlags);
7845+
copyFrom(orig);
7846+
}
7847+
78537848
@Override
78547849
public String toString() {
78557850
return "PackageSetting{"
@@ -8062,21 +8057,29 @@ SharedUserSetting getSharedUserLP(String name,
80628057
return s;
80638058
}
80648059

8065-
int disableSystemPackageLP(String name) {
8060+
boolean disableSystemPackageLP(String name) {
80668061
PackageSetting p = mPackages.get(name);
80678062
if(p == null) {
80688063
Log.w(TAG, "Package:"+name+" is not an installed package");
8069-
return -1;
8064+
return false;
80708065
}
80718066
PackageSetting dp = mDisabledSysPackages.get(name);
80728067
// always make sure the system package code and resource paths dont change
8073-
if(dp == null) {
8068+
if (dp == null) {
80748069
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
80758070
p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
80768071
}
80778072
mDisabledSysPackages.put(name, p);
8073+
8074+
// a little trick... when we install the new package, we don't
8075+
// want to modify the existing PackageSetting for the built-in
8076+
// version. so at this point we need a new PackageSetting that
8077+
// is okay to much with.
8078+
PackageSetting newp = new PackageSetting(p);
8079+
replacePackageLP(name, newp);
8080+
return true;
80788081
}
8079-
return removePackageLP(name);
8082+
return false;
80808083
}
80818084

80828085
PackageSetting enableSystemPackageLP(String name) {
@@ -8410,6 +8413,19 @@ private int removePackageLP(String name) {
84108413
return -1;
84118414
}
84128415

8416+
private void replacePackageLP(String name, PackageSetting newp) {
8417+
PackageSetting p = mPackages.get(name);
8418+
if (p != null) {
8419+
if (p.sharedUser != null) {
8420+
p.sharedUser.packages.remove(p);
8421+
p.sharedUser.packages.add(newp);
8422+
} else {
8423+
replaceUserIdLP(p.userId, newp);
8424+
}
8425+
}
8426+
mPackages.put(name, newp);
8427+
}
8428+
84138429
private boolean addUserIdLP(int uid, Object obj, Object name) {
84148430
if (uid >= FIRST_APPLICATION_UID + MAX_APPLICATION_UIDS) {
84158431
return false;
@@ -8472,6 +8488,16 @@ private void removeUserIdLP(int uid) {
84728488
}
84738489
}
84748490

8491+
private void replaceUserIdLP(int uid, Object obj) {
8492+
if (uid >= FIRST_APPLICATION_UID) {
8493+
int N = mUserIds.size();
8494+
final int index = uid - FIRST_APPLICATION_UID;
8495+
if (index < N) mUserIds.set(index, obj);
8496+
} else {
8497+
mOtherUserIds.put(uid, obj);
8498+
}
8499+
}
8500+
84758501
void writeLP() {
84768502
//Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
84778503

0 commit comments

Comments
 (0)