2525import static com .android .internal .util .ArrayUtils .appendInt ;
2626import static com .android .internal .util .ArrayUtils .removeInt ;
2727import static libcore .io .OsConstants .S_ISLNK ;
28+ import static libcore .io .OsConstants .S_IRWXU ;
29+ import static libcore .io .OsConstants .S_IRGRP ;
30+ import static libcore .io .OsConstants .S_IXGRP ;
31+ import static libcore .io .OsConstants .S_IROTH ;
32+ import static libcore .io .OsConstants .S_IXOTH ;
2833
2934import com .android .internal .app .IMediaContainerService ;
3035import com .android .internal .app .ResolverActivity ;
147152import libcore .io .ErrnoException ;
148153import libcore .io .IoUtils ;
149154import libcore .io .Libcore ;
155+ import libcore .io .OsConstants ;
150156import libcore .io .StructStat ;
151157
152158/**
@@ -276,7 +282,7 @@ public class PackageManagerService extends IPackageManager.Stub {
276282 // This is the object monitoring mDrmAppPrivateInstallDir.
277283 final FileObserver mDrmAppInstallObserver ;
278284
279- // Used for priviledge escalation. MUST NOT BE CALLED WITH mPackages
285+ // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
280286 // LOCK HELD. Can be called with mInstallLock held.
281287 final Installer mInstaller ;
282288
@@ -286,6 +292,12 @@ public class PackageManagerService extends IPackageManager.Stub {
286292 final File mAppInstallDir ;
287293 final File mDalvikCacheDir ;
288294
295+ /**
296+ * Directory to which applications installed internally have native
297+ * libraries copied.
298+ */
299+ private File mAppLibInstallDir ;
300+
289301 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
290302 // apps.
291303 final File mDrmAppPrivateInstallDir ;
@@ -1215,6 +1227,7 @@ public PackageManagerService(Context context, boolean factoryTest, boolean onlyC
12151227 }
12161228
12171229 mAppInstallDir = new File (dataDir , "app" );
1230+ mAppLibInstallDir = new File (dataDir , "app-lib" );
12181231 //look for any incomplete package installations
12191232 ArrayList <PackageSetting > deletePkgsList = mSettings .getListOfIncompleteInstallPackagesLPr ();
12201233 //clean up list
@@ -3607,6 +3620,13 @@ private int removeDataDirsLI(String packageName) {
36073620 res = resInner ;
36083621 }
36093622 }
3623+
3624+ final File nativeLibraryFile = new File (mAppLibInstallDir , packageName );
3625+ NativeLibraryHelper .removeNativeBinariesFromDirLI (nativeLibraryFile );
3626+ if (!nativeLibraryFile .delete ()) {
3627+ Slog .w (TAG , "Couldn't delete native library directory " + nativeLibraryFile .getPath ());
3628+ }
3629+
36103630 return res ;
36113631 }
36123632
@@ -4048,9 +4068,7 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
40484068 */
40494069 if (pkg .applicationInfo .nativeLibraryDir == null && pkg .applicationInfo .dataDir != null ) {
40504070 if (pkgSetting .nativeLibraryPathString == null ) {
4051- final String nativeLibraryPath = new File (dataPath , LIB_DIR_NAME ).getPath ();
4052- pkg .applicationInfo .nativeLibraryDir = nativeLibraryPath ;
4053- pkgSetting .nativeLibraryPathString = nativeLibraryPath ;
4071+ setInternalAppNativeLibraryPath (pkg , pkgSetting );
40544072 } else {
40554073 pkg .applicationInfo .nativeLibraryDir = pkgSetting .nativeLibraryPathString ;
40564074 }
@@ -4072,7 +4090,7 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
40724090 */
40734091 if (pkg .applicationInfo .nativeLibraryDir != null ) {
40744092 try {
4075- final File nativeLibraryDir = new File (pkg .applicationInfo .nativeLibraryDir );
4093+ File nativeLibraryDir = new File (pkg .applicationInfo .nativeLibraryDir );
40764094 final String dataPathString = dataPath .getCanonicalPath ();
40774095
40784096 if (isSystemApp (pkg ) && !isUpdatedSystemApp (pkg )) {
@@ -4087,30 +4105,31 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
40874105 Log .i (TAG , "removed obsolete native libraries for system package "
40884106 + path );
40894107 }
4090- } else if (nativeLibraryDir .getParentFile ().getCanonicalPath ()
4091- .equals (dataPathString )) {
4092- /*
4093- * Make sure the native library dir isn't a symlink to
4094- * something. If it is, ask installd to remove it and create
4095- * a directory so we can copy to it afterwards.
4096- */
4097- boolean isSymLink ;
4098- try {
4099- isSymLink = S_ISLNK (Libcore .os .lstat (nativeLibraryDir .getPath ()).st_mode );
4100- } catch (ErrnoException e ) {
4101- // This shouldn't happen, but we'll fail-safe.
4102- isSymLink = true ;
4108+ } else if (!isForwardLocked (pkg ) && !isExternal (pkg )) {
4109+ // Update native library dir if it starts with /data/data
4110+ if (nativeLibraryDir .getParent ().startsWith (dataPathString )) {
4111+ setInternalAppNativeLibraryPath (pkg , pkgSetting );
4112+ nativeLibraryDir = new File (pkg .applicationInfo .nativeLibraryDir );
41034113 }
4104- if (isSymLink ) {
4105- mInstaller .unlinkNativeLibraryDirectory (dataPathString );
4114+
4115+ try {
4116+ if (copyNativeLibrariesForInternalApp (scanFile , nativeLibraryDir ) != PackageManager .INSTALL_SUCCEEDED ) {
4117+ Slog .e (TAG , "Unable to copy native libraries" );
4118+ mLastScanError = PackageManager .INSTALL_FAILED_INTERNAL_ERROR ;
4119+ return null ;
4120+ }
4121+ } catch (IOException e ) {
4122+ Slog .e (TAG , "Unable to copy native libraries" , e );
4123+ mLastScanError = PackageManager .INSTALL_FAILED_INTERNAL_ERROR ;
4124+ return null ;
41064125 }
41074126
4108- /*
4109- * If this is an internal application or our
4110- * nativeLibraryPath points to our data directory, unpack
4111- * the libraries if necessary.
4112- */
4113- NativeLibraryHelper . copyNativeBinariesIfNeededLI ( scanFile , nativeLibraryDir );
4127+ if ( mInstaller . linkNativeLibraryDirectory ( dataPathString ,
4128+ pkg . applicationInfo . nativeLibraryDir ) == - 1 ) {
4129+ Slog . e ( TAG , "Unable to link native library directory" );
4130+ mLastScanError = PackageManager . INSTALL_FAILED_INTERNAL_ERROR ;
4131+ return null ;
4132+ }
41144133 } else {
41154134 Slog .i (TAG , "Linking native library dir for " + path );
41164135 int ret = mInstaller .linkNativeLibraryDirectory (dataPathString ,
@@ -4122,7 +4141,7 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
41224141 }
41234142 }
41244143 } catch (IOException ioe ) {
4125- Log .e (TAG , "Unable to get canonical file " + ioe .toString ());
4144+ Slog .e (TAG , "Unable to get canonical file " + ioe .toString ());
41264145 }
41274146 }
41284147 pkg .mScanPath = path ;
@@ -4437,6 +4456,37 @@ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
44374456 return pkg ;
44384457 }
44394458
4459+ private void setInternalAppNativeLibraryPath (PackageParser .Package pkg ,
4460+ PackageSetting pkgSetting ) {
4461+ final String apkLibPath = getApkName (pkgSetting .codePathString );
4462+ final String nativeLibraryPath = new File (mAppLibInstallDir , apkLibPath ).getPath ();
4463+ pkg .applicationInfo .nativeLibraryDir = nativeLibraryPath ;
4464+ pkgSetting .nativeLibraryPathString = nativeLibraryPath ;
4465+ }
4466+
4467+ private static int copyNativeLibrariesForInternalApp (File scanFile , final File nativeLibraryDir )
4468+ throws IOException {
4469+ if (!nativeLibraryDir .isDirectory ()) {
4470+ nativeLibraryDir .delete ();
4471+ if (!nativeLibraryDir .mkdir ()) {
4472+ throw new IOException ("Cannot create " + nativeLibraryDir .getPath ());
4473+ }
4474+ try {
4475+ Libcore .os .chmod (nativeLibraryDir .getPath (), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
4476+ | S_IXOTH );
4477+ } catch (ErrnoException e ) {
4478+ throw new IOException ("Cannot chmod native library directory "
4479+ + nativeLibraryDir .getPath (), e );
4480+ }
4481+ }
4482+
4483+ /*
4484+ * If this is an internal application or our nativeLibraryPath points to
4485+ * the app-lib directory, unpack the libraries if necessary.
4486+ */
4487+ return NativeLibraryHelper .copyNativeBinariesIfNeededLI (scanFile , nativeLibraryDir );
4488+ }
4489+
44404490 private void killApplication (String pkgName , int appId ) {
44414491 // Request the ActivityManager to kill the process(only for existing packages)
44424492 // so that we do not end up in a confused state while the user is still using the older
@@ -6737,7 +6787,7 @@ class FileInstallArgs extends InstallArgs {
67376787 String apkName = getNextCodePath (null , pkgName , ".apk" );
67386788 codeFileName = new File (installDir , apkName + ".apk" ).getPath ();
67396789 resourceFileName = getResourcePathFromCodePath ();
6740- libraryPath = new File (dataDir , LIB_DIR_NAME ).getPath ();
6790+ libraryPath = new File (mAppLibInstallDir , pkgName ).getPath ();
67416791 }
67426792
67436793 boolean checkFreeStorage (IMediaContainerService imcs ) throws RemoteException {
@@ -6774,6 +6824,7 @@ void createCopyFile() {
67746824 installDir = isFwdLocked () ? mDrmAppPrivateInstallDir : mAppInstallDir ;
67756825 codeFileName = createTempPackageFile (installDir ).getPath ();
67766826 resourceFileName = getResourcePathFromCodePath ();
6827+ libraryPath = getLibraryPathFromCodePath ();
67776828 created = true ;
67786829 }
67796830
@@ -6828,6 +6879,23 @@ int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
68286879 return PackageManager .INSTALL_FAILED_INSUFFICIENT_STORAGE ;
68296880 }
68306881 }
6882+
6883+ final File nativeLibraryFile = new File (getNativeLibraryPath ());
6884+ Slog .i (TAG , "Copying native libraries to " + nativeLibraryFile .getPath ());
6885+ if (nativeLibraryFile .exists ()) {
6886+ NativeLibraryHelper .removeNativeBinariesFromDirLI (nativeLibraryFile );
6887+ nativeLibraryFile .delete ();
6888+ }
6889+ try {
6890+ int copyRet = copyNativeLibrariesForInternalApp (codeFile , nativeLibraryFile );
6891+ if (copyRet != PackageManager .INSTALL_SUCCEEDED ) {
6892+ return copyRet ;
6893+ }
6894+ } catch (IOException e ) {
6895+ Slog .e (TAG , "Copying native libraries failed" , e );
6896+ ret = PackageManager .INSTALL_FAILED_INTERNAL_ERROR ;
6897+ }
6898+
68316899 return ret ;
68326900 }
68336901
@@ -6845,6 +6913,7 @@ boolean doRename(int status, final String pkgName, String oldCodePath) {
68456913 } else {
68466914 final File oldCodeFile = new File (getCodePath ());
68476915 final File oldResourceFile = new File (getResourcePath ());
6916+ final File oldLibraryFile = new File (getNativeLibraryPath ());
68486917
68496918 // Rename APK file based on packageName
68506919 final String apkName = getNextCodePath (oldCodePath , pkgName , ".apk" );
@@ -6859,7 +6928,20 @@ boolean doRename(int status, final String pkgName, String oldCodePath) {
68596928 if (isFwdLocked () && !oldResourceFile .renameTo (newResFile )) {
68606929 return false ;
68616930 }
6862- resourceFileName = getResourcePathFromCodePath ();
6931+ resourceFileName = newResFile .getPath ();
6932+
6933+ // Rename library path
6934+ final File newLibraryFile = new File (getLibraryPathFromCodePath ());
6935+ if (newLibraryFile .exists ()) {
6936+ NativeLibraryHelper .removeNativeBinariesFromDirLI (newLibraryFile );
6937+ newLibraryFile .delete ();
6938+ }
6939+ if (!oldLibraryFile .renameTo (newLibraryFile )) {
6940+ Slog .e (TAG , "Cannot rename native library directory "
6941+ + oldLibraryFile .getPath () + " to " + newLibraryFile .getPath ());
6942+ return false ;
6943+ }
6944+ libraryPath = newLibraryFile .getPath ();
68636945
68646946 // Attempt to set permissions
68656947 if (!setPermissions ()) {
@@ -6910,8 +6992,15 @@ private String getResourcePathFromCodePath() {
69106992 }
69116993 }
69126994
6995+ private String getLibraryPathFromCodePath () {
6996+ return new File (mAppLibInstallDir , getApkName (getCodePath ())).getPath ();
6997+ }
6998+
69136999 @ Override
69147000 String getNativeLibraryPath () {
7001+ if (libraryPath == null ) {
7002+ libraryPath = getLibraryPathFromCodePath ();
7003+ }
69157004 return libraryPath ;
69167005 }
69177006
@@ -6937,6 +7026,15 @@ private boolean cleanUp() {
69377026 publicSourceFile .delete ();
69387027 }
69397028 }
7029+
7030+ if (libraryPath != null ) {
7031+ File nativeLibraryFile = new File (libraryPath );
7032+ NativeLibraryHelper .removeNativeBinariesFromDirLI (nativeLibraryFile );
7033+ if (!nativeLibraryFile .delete ()) {
7034+ Slog .w (TAG , "Couldn't delete native library directory " + libraryPath );
7035+ }
7036+ }
7037+
69407038 return ret ;
69417039 }
69427040
@@ -9779,31 +9877,26 @@ public void run() {
97799877 final String newNativePath = mp .targetArgs
97809878 .getNativeLibraryPath ();
97819879
9782- try {
9783- final File newNativeDir = new File (newNativePath );
9880+ final File newNativeDir = new File (newNativePath );
97849881
9785- final String libParentDir = newNativeDir .getParentFile ()
9786- .getCanonicalPath ();
9787- if (newNativeDir .getParentFile ().getCanonicalPath ()
9788- .equals (pkg .applicationInfo .dataDir )) {
9789- if (mInstaller
9790- .unlinkNativeLibraryDirectory (pkg .applicationInfo .dataDir ) < 0 ) {
9882+ if (!isForwardLocked (pkg ) && !isExternal (pkg )) {
9883+ synchronized (mInstallLock ) {
9884+ if (mInstaller .linkNativeLibraryDirectory (
9885+ pkg .applicationInfo .dataDir , newNativePath ) < 0 ) {
97919886 returnCode = PackageManager .MOVE_FAILED_INSUFFICIENT_STORAGE ;
9792- } else {
9793- NativeLibraryHelper .copyNativeBinariesIfNeededLI (
9794- new File (newCodePath ), newNativeDir );
97959887 }
9796- } else {
9888+ }
9889+ NativeLibraryHelper .copyNativeBinariesIfNeededLI (new File (
9890+ newCodePath ), newNativeDir );
9891+ } else {
9892+ synchronized (mInstallLock ) {
97979893 if (mInstaller .linkNativeLibraryDirectory (
97989894 pkg .applicationInfo .dataDir , newNativePath ) < 0 ) {
97999895 returnCode = PackageManager .MOVE_FAILED_INSUFFICIENT_STORAGE ;
98009896 }
98019897 }
9802- } catch (IOException e ) {
9803- returnCode = PackageManager .MOVE_FAILED_INVALID_LOCATION ;
98049898 }
98059899
9806-
98079900 if (returnCode == PackageManager .MOVE_SUCCEEDED ) {
98089901 pkg .mPath = newCodePath ;
98099902 // Move dex files around
0 commit comments