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

Commit 2454a5f8 authored by Khaled Abdelmohsen's avatar Khaled Abdelmohsen Committed by Android (Google) Code Review
Browse files

Merge "Match rules against app install metadata"

parents 701edd6c 29be9648
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ public final class RuleEvaluationEngine {
                case DENY:
                    return IntegrityCheckResult.deny(matchedRule);
                default:
                    Slog.i(TAG, "Matched a non-DENY rule: " + matchedRule);
                    Slog.e(TAG, "Matched a non-DENY rule: " + matchedRule);
                    return IntegrityCheckResult.allow();
            }
        }
+54 −1
Original line number Diff line number Diff line
@@ -16,7 +16,12 @@

package com.android.server.integrity.engine;

import android.util.Slog;

import com.android.server.integrity.model.AppInstallMetadata;
import com.android.server.integrity.model.AtomicFormula;
import com.android.server.integrity.model.Formula;
import com.android.server.integrity.model.OpenFormula;
import com.android.server.integrity.model.Rule;

import java.util.List;
@@ -27,6 +32,8 @@ import java.util.List;
 */
final class RuleEvaluator {

    private static final String TAG = "RuleEvaluator";

    /**
     * Match the list of rules against an app install metadata.
     *
@@ -45,8 +52,54 @@ final class RuleEvaluator {
        return Rule.EMPTY;
    }

    /**
     * Match a rule against app install metadata.
     */
    private static boolean isMatch(Rule rule, AppInstallMetadata appInstallMetadata) {
        // TODO: Add matching logic
        return isMatch(rule.getFormula(), appInstallMetadata);
    }

    private static boolean isMatch(Formula formula, AppInstallMetadata appInstallMetadata) {
        if (formula instanceof AtomicFormula) {
            AtomicFormula atomicFormula = (AtomicFormula) formula;
            switch (atomicFormula.getKey()) {
                case PACKAGE_NAME:
                    return atomicFormula.isMatch(appInstallMetadata.getPackageName());
                case APP_CERTIFICATE:
                    return atomicFormula.isMatch(appInstallMetadata.getAppCertificate());
                case INSTALLER_NAME:
                    return atomicFormula.isMatch(appInstallMetadata.getInstallerName());
                case INSTALLER_CERTIFICATE:
                    return atomicFormula.isMatch(appInstallMetadata.getInstallerCertificate());
                case VERSION_CODE:
                    return atomicFormula.isMatch(appInstallMetadata.getVersionCode());
                case PRE_INSTALLED:
                    return atomicFormula.isMatch(appInstallMetadata.isPreInstalled());
                default:
                    Slog.i(TAG, String.format("Returned no match for unknown key %s",
                            atomicFormula.getKey()));
                    return false;
            }
        } else if (formula instanceof OpenFormula) {
            OpenFormula openFormula = (OpenFormula) formula;
            // A rule is in disjunctive normal form, so there are no OR connectors.
            switch (openFormula.getConnector()) {
                case NOT:
                    // NOT connector has only 1 formula attached.
                    return !isMatch(openFormula.getFormulas().get(0), appInstallMetadata);
                case AND:
                    boolean result = true;
                    for (Formula subFormula : openFormula.getFormulas()) {
                        result &= isMatch(subFormula, appInstallMetadata);
                    }
                    return result;
                default:
                    Slog.i(TAG, String.format("Returned no match for unknown connector %s",
                            openFormula.getConnector()));
                    return false;
            }
        }

        return false;
    }
}
+59 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;

import android.annotation.Nullable;
import android.util.Slog;

/**
 * Represents a simple formula consisting of an app install metadata field and a value.
@@ -28,7 +29,9 @@ import android.annotation.Nullable;
 */
public final class AtomicFormula extends Formula {

    enum Key {
    private static final String TAG = "AtomicFormula";

    public enum Key {
        PACKAGE_NAME,
        APP_CERTIFICATE,
        INSTALLER_NAME,
@@ -37,7 +40,7 @@ public final class AtomicFormula extends Formula {
        PRE_INSTALLED
    }

    enum Operator {
    public enum Operator {
        EQ,
        LT,
        LE,
@@ -132,6 +135,59 @@ public final class AtomicFormula extends Formula {
        return String.format("%s %s %s", mKey, mOperator, getValue());
    }

    /**
     * Check if the formula is true when substituting its {@link Key} with the string value.
     *
     * @param value String value to substitute the key with.
     * @return {@code true} if the formula is true, and {@code false} otherwise.
     */
    public boolean isMatch(String value) {
        switch (mOperator) {
            case EQ:
                return mStringValue.equals(value);
        }
        Slog.i(TAG, String.format("Found operator %s for value %s", mOperator, mStringValue));
        return false;
    }

    /**
     * Check if the formula is true when substituting its {@link Key} with the integer value.
     *
     * @param value Integer value to substitute the key with.
     * @return {@code true} if the formula is true, and {@code false} otherwise.
     */
    public boolean isMatch(int value) {
        switch (mOperator) {
            case EQ:
                return mIntValue == value;
            case LE:
                return mIntValue <= value;
            case LT:
                return mIntValue < value;
            case GE:
                return mIntValue >= value;
            case GT:
                return mIntValue > value;
        }
        Slog.i(TAG, String.format("Found operator %s for value %s", mOperator, mIntValue));
        return false;
    }

    /**
     * Check if the formula is true when substituting its {@link Key} with the boolean value.
     *
     * @param value Boolean value to substitute the key with.
     * @return {@code true} if the formula is true, and {@code false} otherwise.
     */
    public boolean isMatch(boolean value) {
        switch (mOperator) {
            case EQ:
                return mBoolValue == value;
        }
        Slog.i(TAG, String.format("Found operator %s for value %s", mOperator, mBoolValue));
        return false;
    }

    private void validateOperator(Key key, Operator operator) {
        boolean validOperator;
        switch (key) {
@@ -146,6 +202,7 @@ public final class AtomicFormula extends Formula {
                validOperator = true;
                break;
            default:
                Slog.i(TAG, String.format("Found operator %s for key %s", operator, key));
                validOperator = false;
        }
        if (!validOperator) {
+1 −1
Original line number Diff line number Diff line
@@ -19,6 +19,6 @@ package com.android.server.integrity.model;
/**
 * Represents a rule logic/content.
 */
abstract class Formula {
public abstract class Formula {

}
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ import java.util.List;
 */
public final class OpenFormula extends Formula {

    enum Connector {
    public enum Connector {
        AND,
        OR,
        NOT
Loading