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

Commit 1b9b59c6 authored by Oli Lan's avatar Oli Lan
Browse files

Validate package name passed to setApplicationRestrictions. (Reland)

This adds validation that the package name passed to
setApplicationRestrictions is in the correct format. This will avoid
an issue where a path could be entered resulting in a file being
written to an unexpected place.

Bug: 239701237
Merged-In: I1ab2b7228470f10ec26fe3a608ae540cfc9e9a96
Change-Id: I56c2fc14f906cdad80181ab577e2ebc276c151c1
parent c448026a
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import android.stats.devicepolicy.DevicePolicyEnums;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.EventLog;
import android.util.IndentingPrintWriter;
import android.util.IntArray;
import android.util.Slog;
@@ -4499,6 +4500,13 @@ public class UserManagerService extends IUserManager.Stub {
    public void setApplicationRestrictions(String packageName, Bundle restrictions,
            @UserIdInt int userId) {
        checkSystemOrRoot("set application restrictions");
        String validationResult = validateName(packageName);
        if (validationResult != null) {
            if (packageName.contains("../")) {
                EventLog.writeEvent(0x534e4554, "239701237", -1, "");
            }
            throw new IllegalArgumentException("Invalid package name: " + validationResult);
        }
        if (restrictions != null) {
            restrictions.setDefusable(true);
        }
@@ -4525,6 +4533,39 @@ public class UserManagerService extends IUserManager.Stub {
        mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));
    }

    /**
     * Check if the given name is valid.
     *
     * Note: the logic is taken from FrameworkParsingPackageUtils in master, edited to remove
     * unnecessary parts. Copied here for a security fix.
     *
     * @param name The name to check.
     * @return null if it's valid, error message if not
     */
    @VisibleForTesting
    static String validateName(String name) {
        final int n = name.length();
        boolean front = true;
        for (int i = 0; i < n; i++) {
            final char c = name.charAt(i);
            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
                front = false;
                continue;
            }
            if (!front) {
                if ((c >= '0' && c <= '9') || c == '_') {
                    continue;
                }
                if (c == '.') {
                    front = true;
                    continue;
                }
            }
            return "bad character '" + c + "'";
        }
        return null;
    }

    private int getUidForPackage(String packageName) {
        final long ident = Binder.clearCallingIdentity();
        try {