Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f29131f7 authored by Narayan Kamath's avatar Narayan Kamath Committed by Android (Google) Code Review
Browse files

Merge "Fix native crashes when APKs can't be opened."

parents 71420b89 cef0b39b
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.content;
import android.content.pm.PackageManager;
import android.util.Slog;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;

@@ -39,20 +40,29 @@ public class NativeLibraryHelper {
     *
     * @hide
     */
    public static class ApkHandle {
    public static class ApkHandle implements Closeable {
        final String apkPath;
        final long apkHandle;

        public ApkHandle(String path) {
            apkPath = path;
            apkHandle = nativeOpenApk(apkPath);
        public static ApkHandle create(String path) throws IOException {
            final long handle = nativeOpenApk(path);
            if (handle == 0) {
                throw new IOException("Unable to open APK: " + path);
            }

        public ApkHandle(File apkFile) {
            apkPath = apkFile.getPath();
            apkHandle = nativeOpenApk(apkPath);
            return new ApkHandle(path, handle);
        }

        public static ApkHandle create(File path) throws IOException {
            return create(path.getAbsolutePath());
        }

        private ApkHandle(String apkPath, long apkHandle) {
            this.apkPath = apkPath;
            this.apkHandle = apkHandle;
        }

        @Override
        public void close() {
            nativeClose(apkHandle);
        }
+29 −19
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.util.Slog;

import com.android.internal.app.IMediaContainerService;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.NativeLibraryHelper.ApkHandle;
import com.android.internal.content.PackageHelper;

import java.io.BufferedInputStream;
@@ -107,8 +108,27 @@ public class DefaultContainerService extends IntentService {
                return null;
            }


            if (isExternal) {
                // Make sure the sdcard is mounted.
                String status = Environment.getExternalStorageState();
                if (!status.equals(Environment.MEDIA_MOUNTED)) {
                    Slog.w(TAG, "Make sure sdcard is mounted.");
                    return null;
                }
            }

            ApkHandle handle = null;
            try {
                handle = ApkHandle.create(packageURI.getPath());
                return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName,
                    isExternal, isForwardLocked, abiOverride);
                        isExternal, isForwardLocked, handle, abiOverride);
            } catch (IOException ioe) {
                Slog.w(TAG, "Problem opening APK: " + packageURI.getPath());
                return null;
            } finally {
                IoUtils.closeQuietly(handle);
            }
        }

        /**
@@ -329,21 +349,11 @@ public class DefaultContainerService extends IntentService {

    private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName,
            String publicResFileName, boolean isExternal, boolean isForwardLocked,
            String abiOverride) {

        if (isExternal) {
            // Make sure the sdcard is mounted.
            String status = Environment.getExternalStorageState();
            if (!status.equals(Environment.MEDIA_MOUNTED)) {
                Slog.w(TAG, "Make sure sdcard is mounted.");
                return null;
            }
        }

            ApkHandle handle, String abiOverride) {
        // The .apk file
        String codePath = packageURI.getPath();
        File codeFile = new File(codePath);
        NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codePath);

        String[] abiList = Build.SUPPORTED_ABIS;
        if (abiOverride != null) {
            abiList = new String[] { abiOverride };
@@ -850,14 +860,14 @@ public class DefaultContainerService extends IntentService {

    private int calculateContainerSize(File apkFile, boolean forwardLocked,
            String abiOverride) throws IOException {
        NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(apkFile);
        ApkHandle handle = null;
        try {
            handle = ApkHandle.create(apkFile);
            final int abi = NativeLibraryHelper.findSupportedAbi(handle,
                    (abiOverride != null) ? new String[] { abiOverride } : Build.SUPPORTED_ABIS);

        try {
            return calculateContainerSize(handle, apkFile, abi, forwardLocked);
        } finally {
            handle.close();
            IoUtils.closeQuietly(handle);
        }
    }

+7 −2
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;

import libcore.io.IoUtils;
import libcore.io.Libcore;

import java.io.File;
@@ -449,8 +450,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }

        for (File file : files) {
            final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(file);
            NativeLibraryHelper.ApkHandle handle = null;
            try {
                handle = NativeLibraryHelper.ApkHandle.create(file);
                final int abiIndex = NativeLibraryHelper.findSupportedAbi(handle,
                        Build.SUPPORTED_ABIS);
                if (abiIndex >= 0) {
@@ -464,8 +466,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    throw new InstallFailedException(abiIndex,
                            "Failed to copy native libraries for " + file);
                }
            } catch (IOException ioe) {
                throw new InstallFailedException(INSTALL_FAILED_INTERNAL_ERROR,
                        "Failed to create handle for " + file);
            } finally {
                handle.close();
                IoUtils.closeQuietly(handle);
            }
        }
    }
+27 −18
Original line number Diff line number Diff line
@@ -5339,8 +5339,9 @@ public class PackageManagerService extends IPackageManager.Stub {
         */
        if (pkg.applicationInfo.nativeLibraryDir != null) {
            // TODO: extend to extract native code from split APKs
            final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
            ApkHandle handle = null;
            try {
                handle = ApkHandle.create(scanFile.getPath());
                // Enable gross and lame hacks for apps that are built with old
                // SDK tools. We must scan their APKs for renderscript bitcode and
                // not launch them if it's present. Don't bother checking on devices
@@ -5455,7 +5456,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            } catch (IOException ioe) {
                Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
            } finally {
                handle.close();
                IoUtils.closeQuietly(handle);
            }
        }
@@ -9171,10 +9172,11 @@ public class PackageManagerService extends IPackageManager.Stub {
                nativeLibraryFile.delete();
            }
            final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codeFile);
            String[] abiList = (abiOverride != null) ?
                    new String[] { abiOverride } : Build.SUPPORTED_ABIS;
            ApkHandle handle = null;
            try {
                handle = ApkHandle.create(codeFile);
                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
                        abiOverride == null &&
                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
@@ -9189,7 +9191,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                Slog.e(TAG, "Copying native libraries failed", e);
                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
            } finally {
                handle.close();
                IoUtils.closeQuietly(handle);
            }
            return ret;
@@ -12852,25 +12854,32 @@ public class PackageManagerService extends IPackageManager.Stub {
                                    final File newNativeDir = new File(newNativePath);
                                    if (!isForwardLocked(pkg) && !isExternal(pkg)) {
                                        // NOTE: We do not report any errors from the APK scan and library
                                        // copy at this point.
                                        NativeLibraryHelper.ApkHandle handle =
                                                new NativeLibraryHelper.ApkHandle(newCodePath);
                                        ApkHandle handle = null;
                                        try {
                                            handle = ApkHandle.create(newCodePath);
                                            final int abi = NativeLibraryHelper.findSupportedAbi(
                                                    handle, Build.SUPPORTED_ABIS);
                                            if (abi >= 0) {
                                                NativeLibraryHelper.copyNativeBinariesIfNeededLI(
                                                        handle, newNativeDir, Build.SUPPORTED_ABIS[abi]);
                                            }
                                        handle.close();
                                        } catch (IOException ioe) {
                                            Slog.w(TAG, "Unable to extract native libs for package :"
                                                    + mp.packageName, ioe);
                                            returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
                                        } finally {
                                            IoUtils.closeQuietly(handle);
                                        }
                                    }
                                    final int[] users = sUserManager.getUserIds();
                                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
                                        for (int user : users) {
                                            if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
                                                    newNativePath, user) < 0) {
                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
                                            }
                                        }
                                    }
                                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
                                        pkg.codePath = newCodePath;