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

Commit 6c4b9de8 authored by Narayan Kamath's avatar Narayan Kamath
Browse files

Validate instruction sets passed to installd.

We don't want folks passing down arbitrary strings.

bug: 16837404
Change-Id: I73ac66b376f1401f9f95f3c6323da6242ac8ed3d
parent 4b2d0f20
Loading
Loading
Loading
Loading
+0 −4
Original line number Original line Diff line number Diff line
@@ -262,10 +262,6 @@ public final class LoadedApk {
                if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) {
                if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) {
                    final String isa = VMRuntime.getRuntime().vmInstructionSet();
                    final String isa = VMRuntime.getRuntime().vmInstructionSet();
                    try {
                    try {
                        // TODO: We can probably do away with the isa argument since
                        // the AM and PM have enough information to figure this out
                        // themselves. If we do need it, we should match it against the
                        // list of devices ISAs before sending it down to installd.
                        ActivityThread.getPackageManager().performDexOptIfNeeded(mPackageName, isa);
                        ActivityThread.getPackageManager().performDexOptIfNeeded(mPackageName, isa);
                    } catch (RemoteException re) {
                    } catch (RemoteException re) {
                        // Ignored.
                        // Ignored.
+56 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.pm;
package com.android.server.pm;


import android.os.Build;
import com.android.server.SystemService;
import com.android.server.SystemService;


import android.content.Context;
import android.content.Context;
@@ -23,6 +24,7 @@ import android.content.pm.PackageStats;
import android.net.LocalSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.net.LocalSocketAddress;
import android.util.Slog;
import android.util.Slog;
import dalvik.system.VMRuntime;


import java.io.IOException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStream;
@@ -214,6 +216,11 @@ public final class Installer extends SystemService {


    public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
    public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
            String instructionSet) {
            String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        StringBuilder builder = new StringBuilder("patchoat");
        StringBuilder builder = new StringBuilder("patchoat");
        builder.append(' ');
        builder.append(' ');
        builder.append(apkPath);
        builder.append(apkPath);
@@ -228,6 +235,11 @@ public final class Installer extends SystemService {
    }
    }


    public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
    public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        StringBuilder builder = new StringBuilder("patchoat");
        StringBuilder builder = new StringBuilder("patchoat");
        builder.append(' ');
        builder.append(' ');
        builder.append(apkPath);
        builder.append(apkPath);
@@ -241,6 +253,11 @@ public final class Installer extends SystemService {
    }
    }


    public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
    public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        StringBuilder builder = new StringBuilder("dexopt");
        StringBuilder builder = new StringBuilder("dexopt");
        builder.append(' ');
        builder.append(' ');
        builder.append(apkPath);
        builder.append(apkPath);
@@ -255,6 +272,11 @@ public final class Installer extends SystemService {


    public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
    public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
            String instructionSet) {
            String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        StringBuilder builder = new StringBuilder("dexopt");
        StringBuilder builder = new StringBuilder("dexopt");
        builder.append(' ');
        builder.append(' ');
        builder.append(apkPath);
        builder.append(apkPath);
@@ -280,6 +302,11 @@ public final class Installer extends SystemService {
    }
    }


    public int movedex(String srcPath, String dstPath, String instructionSet) {
    public int movedex(String srcPath, String dstPath, String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        StringBuilder builder = new StringBuilder("movedex");
        StringBuilder builder = new StringBuilder("movedex");
        builder.append(' ');
        builder.append(' ');
        builder.append(srcPath);
        builder.append(srcPath);
@@ -291,6 +318,11 @@ public final class Installer extends SystemService {
    }
    }


    public int rmdex(String codePath, String instructionSet) {
    public int rmdex(String codePath, String instructionSet) {
        if (!isValidInstructionSet(instructionSet)) {
            Slog.e(TAG, "Invalid instruction set: " + instructionSet);
            return -1;
        }

        StringBuilder builder = new StringBuilder("rmdex");
        StringBuilder builder = new StringBuilder("rmdex");
        builder.append(' ');
        builder.append(' ');
        builder.append(codePath);
        builder.append(codePath);
@@ -403,6 +435,13 @@ public final class Installer extends SystemService {


    public int getSizeInfo(String pkgName, int persona, String apkPath, String libDirPath,
    public int getSizeInfo(String pkgName, int persona, String apkPath, String libDirPath,
            String fwdLockApkPath, String asecPath, String[] instructionSets, PackageStats pStats) {
            String fwdLockApkPath, String asecPath, String[] instructionSets, PackageStats pStats) {
        for (String instructionSet : instructionSets) {
            if (!isValidInstructionSet(instructionSet)) {
                Slog.e(TAG, "Invalid instruction set: " + instructionSet);
                return -1;
            }
        }

        StringBuilder builder = new StringBuilder("getsize");
        StringBuilder builder = new StringBuilder("getsize");
        builder.append(' ');
        builder.append(' ');
        builder.append(pkgName);
        builder.append(pkgName);
@@ -480,4 +519,21 @@ public final class Installer extends SystemService {
        builder.append(uid);
        builder.append(uid);
        return (execute(builder.toString()) == 0);
        return (execute(builder.toString()) == 0);
    }
    }

    /**
     * Returns true iff. {@code instructionSet} is a valid instruction set.
     */
    private static boolean isValidInstructionSet(String instructionSet) {
        if (instructionSet == null) {
            return false;
        }

        for (String abi : Build.SUPPORTED_ABIS) {
            if (instructionSet.equals(VMRuntime.getInstructionSet(abi))) {
                return true;
            }
        }

        return false;
    }
}
}