@@ -191,6 +191,7 @@ public class PackageManagerService extends IPackageManager.Stub {
191191 static final int SCAN_NO_PATHS = 1 <<5 ;
192192 static final int SCAN_UPDATE_TIME = 1 <<6 ;
193193 static final int SCAN_DEFER_DEX = 1 <<7 ;
194+ static final int SCAN_BOOTING = 1 <<8 ;
194195
195196 static final int REMOVE_CHATTY = 1 <<16 ;
196197
@@ -924,7 +925,7 @@ public PackageManagerService(Context context, boolean factoryTest, boolean onlyC
924925
925926 // Set flag to monitor and not change apk file paths when
926927 // scanning install directories.
927- int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX ;
928+ int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING ;
928929 if (mNoDexOpt ) {
929930 Slog .w (TAG , "Running ENG build: no pre-dexopt!" );
930931 scanMode |= SCAN_NO_DEX ;
@@ -3750,17 +3751,34 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
37503751 } else {
37513752 // This is a normal package, need to make its data directory.
37523753 dataPath = getDataPathForPackage (pkg .packageName , 0 );
3753-
3754+
37543755 boolean uidError = false ;
3755-
3756+
37563757 if (dataPath .exists ()) {
3758+ // XXX should really do this check for each user.
37573759 mOutPermissions [1 ] = 0 ;
37583760 FileUtils .getPermissions (dataPath .getPath (), mOutPermissions );
37593761
37603762 // If we have mismatched owners for the data path, we have a problem.
37613763 if (mOutPermissions [1 ] != pkg .applicationInfo .uid ) {
37623764 boolean recovered = false ;
3763- if ((parseFlags &PackageParser .PARSE_IS_SYSTEM ) != 0 ) {
3765+ if (mOutPermissions [1 ] == 0 ) {
3766+ // The directory somehow became owned by root. Wow.
3767+ // This is probably because the system was stopped while
3768+ // installd was in the middle of messing with its libs
3769+ // directory. Ask installd to fix that.
3770+ int ret = mInstaller .fixUid (pkgName , pkg .applicationInfo .uid ,
3771+ pkg .applicationInfo .uid );
3772+ if (ret >= 0 ) {
3773+ recovered = true ;
3774+ String msg = "Package " + pkg .packageName
3775+ + " unexpectedly changed to uid 0; recovered to " +
3776+ + pkg .applicationInfo .uid ;
3777+ reportSettingsProblem (Log .WARN , msg );
3778+ }
3779+ }
3780+ if (!recovered && ((parseFlags &PackageParser .PARSE_IS_SYSTEM ) != 0
3781+ || (scanMode &SCAN_BOOTING ) != 0 )) {
37643782 // If this is a system app, we can at least delete its
37653783 // current data so the application will still work.
37663784 int ret = mInstaller .remove (pkgName , 0 );
@@ -3769,7 +3787,9 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
37693787 // Remove the data directories for all users
37703788 sUserManager .removePackageForAllUsers (pkgName );
37713789 // Old data gone!
3772- String msg = "System package " + pkg .packageName
3790+ String prefix = (parseFlags &PackageParser .PARSE_IS_SYSTEM ) != 0
3791+ ? "System package " : "Third party package " ;
3792+ String msg = prefix + pkg .packageName
37733793 + " has changed from uid: "
37743794 + mOutPermissions [1 ] + " to "
37753795 + pkg .applicationInfo .uid + "; old data erased" ;
@@ -3781,7 +3801,7 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
37813801 pkg .applicationInfo .uid );
37823802 if (ret == -1 ) {
37833803 // Ack should not happen!
3784- msg = "System package " + pkg .packageName
3804+ msg = prefix + pkg .packageName
37853805 + " could not have data directory re-created after delete." ;
37863806 reportSettingsProblem (Log .WARN , msg );
37873807 mLastScanError = PackageManager .INSTALL_FAILED_INSUFFICIENT_STORAGE ;
@@ -3794,6 +3814,11 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
37943814 if (!recovered ) {
37953815 mHasSystemUidErrors = true ;
37963816 }
3817+ } else if (!recovered ) {
3818+ // If we allow this install to proceed, we will be broken.
3819+ // Abort, abort!
3820+ mLastScanError = PackageManager .INSTALL_FAILED_UID_CHANGED ;
3821+ return null ;
37973822 }
37983823 if (!recovered ) {
37993824 pkg .applicationInfo .dataDir = "/mismatched_uid/settings_"
0 commit comments