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

Commit b078f585 authored by Thiébaud Weksteen's avatar Thiébaud Weksteen Committed by Android (Google) Code Review
Browse files

Merge changes Id3754721,I0c419aed into main

* changes:
  Enable SELinux denials collection based on flag
  Add flag for SelinuxAuditLogs
parents 9769ddbc 0890ca43
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ aconfig_declarations_group {
        "android.service.dreams.flags-aconfig-java",
        "android.service.notification.flags-aconfig-java",
        "android.service.quickaccesswallet.flags-aconfig-java",
        "android.service.selinux.flags-aconfig-java",
        "android.service.voice.flags-aconfig-java",
        "android.speech.flags-aconfig-java",
        "android.systemserver.flags-aconfig-java",
@@ -1943,3 +1944,19 @@ java_aconfig_library {
    aconfig_declarations: "android.service.quickaccesswallet.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

// SELinux log collector
aconfig_declarations {
    name: "android.service.selinux.flags-aconfig",
    package: "com.android.server.selinux.flags",
    container: "system",
    srcs: [
        "services/core/java/com/android/server/selinux/*.aconfig",
    ],
}

java_aconfig_library {
    name: "android.service.selinux.flags-aconfig-java",
    aconfig_declarations: "android.service.selinux.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+14 −8
Original line number Diff line number Diff line
@@ -72,14 +72,20 @@ class SelinuxAuditLogsCollector {
    }

    SelinuxAuditLogsCollector(RateLimiter rateLimiter, QuotaLimiter quotaLimiter) {
        this(
                () ->
                        DeviceConfig.getString(
        this(new DefaultDomainSupplier(), rateLimiter, quotaLimiter);
    }

    private static class DefaultDomainSupplier implements Supplier<String> {
        @Override
        public String get() {
            if (SelinuxAuditLogsService.enabledForAllDomains()) {
                return "\\w+";
            }
            return DeviceConfig.getString(
                    DeviceConfig.NAMESPACE_ADSERVICES,
                    CONFIG_SELINUX_AUDIT_DOMAIN,
                                DEFAULT_SELINUX_AUDIT_DOMAIN),
                rateLimiter,
                quotaLimiter);
                    DEFAULT_SELINUX_AUDIT_DOMAIN);
        }
    }

    public void setStopRequested(boolean stopRequested) {
+91 −18
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.selinux;

import static com.android.sdksandbox.flags.Flags.selinuxSdkSandboxAudit;
import static com.android.server.selinux.flags.Flags.selinuxLogsCollect;

import android.app.job.JobInfo;
import android.app.job.JobParameters;
@@ -49,6 +50,9 @@ public class SelinuxAuditLogsService extends JobService {
            "selinux_audit_job_frequency_hours";
    private static final String CONFIG_SELINUX_ENABLE_AUDIT_JOB = "selinux_enable_audit_job";
    private static final String CONFIG_SELINUX_AUDIT_CAP = "selinux_audit_cap";
    private static final String DEVICE_CONFIG_SECURITY_NAMESPACE = "security";
    private static final String CONFIG_SECURITY_SELINUX_AUDIT_JOB_ENABLED =
            "selinux_audit_job_enabled";
    private static final int MAX_PERMITS_CAP_DEFAULT = 50000;

    private static final int SELINUX_AUDIT_JOB_ID = 25327386;
@@ -76,7 +80,7 @@ public class SelinuxAuditLogsService extends JobService {

    /** Schedule jobs with the {@link JobScheduler}. */
    public static void schedule(Context context) {
        if (!selinuxSdkSandboxAudit()) {
        if (!selinuxSdkSandboxAudit() && !enabledForAllDomains()) {
            Slog.d(TAG, "SelinuxAuditLogsService not enabled");
            return;
        }
@@ -86,13 +90,20 @@ public class SelinuxAuditLogsService extends JobService {
            return;
        }

        LogsCollectorJobScheduler propertiesListener =
        LogsCollectorJobScheduler scheduler =
                new LogsCollectorJobScheduler(
                        context.getSystemService(JobScheduler.class)
                                .forNamespace(SELINUX_AUDIT_NAMESPACE));
        propertiesListener.schedule();
        scheduler.schedule();

        AdServicesPropertyMonitor adServicesProperties = new AdServicesPropertyMonitor(scheduler);
        DeviceConfig.addOnPropertiesChangedListener(
                DeviceConfig.NAMESPACE_ADSERVICES, context.getMainExecutor(), adServicesProperties);

        SecurityPropertyMonitor securityProperties = new SecurityPropertyMonitor(scheduler);
        DeviceConfig.addOnPropertiesChangedListener(
                DeviceConfig.NAMESPACE_ADSERVICES, context.getMainExecutor(), propertiesListener);
                DEVICE_CONFIG_SECURITY_NAMESPACE, context.getMainExecutor(), securityProperties);

    }

    @Override
@@ -101,7 +112,7 @@ public class SelinuxAuditLogsService extends JobService {
            Slog.e(TAG, "The job id does not match the expected selinux job id.");
            return false;
        }
        if (!selinuxSdkSandboxAudit()) {
        if (!selinuxSdkSandboxAudit() && !enabledForAllDomains()) {
            Slog.i(TAG, "Selinux audit job disabled.");
            return false;
        }
@@ -123,17 +134,33 @@ public class SelinuxAuditLogsService extends JobService {
        return false;
    }

    /**
     * This class is in charge of scheduling the job service, and keeping the scheduling up to date
     * when the parameters change.
     */
    private static final class LogsCollectorJobScheduler
    /** Checks if the service is enabled for all domains */
    public static final boolean enabledForAllDomains() {
        if (selinuxLogsCollect()) {
            return DeviceConfig.getBoolean(
                    DEVICE_CONFIG_SECURITY_NAMESPACE,
                    CONFIG_SECURITY_SELINUX_AUDIT_JOB_ENABLED,
                    false);
        }
        return false;
    }

    /** Checks if the service is enabled for SDK Sandbox */
    public static final boolean enabledForSdkSandbox() {
        if (selinuxSdkSandboxAudit()) {
            return DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_ADSERVICES, CONFIG_SELINUX_ENABLE_AUDIT_JOB, false);
        }
        return false;
    }

    private static final class AdServicesPropertyMonitor
            implements DeviceConfig.OnPropertiesChangedListener {

        private final JobScheduler mJobScheduler;
        private final LogsCollectorJobScheduler mScheduler;

        private LogsCollectorJobScheduler(JobScheduler jobScheduler) {
            mJobScheduler = jobScheduler;
        private AdServicesPropertyMonitor(LogsCollectorJobScheduler scheduler) {
            mScheduler = scheduler;
        }

        @Override
@@ -149,19 +176,65 @@ public class SelinuxAuditLogsService extends JobService {
            if (keyset.contains(CONFIG_SELINUX_ENABLE_AUDIT_JOB)) {
                boolean enabled =
                        changedProperties.getBoolean(
                                CONFIG_SELINUX_ENABLE_AUDIT_JOB, /* defaultValue= */ false);
                                CONFIG_SELINUX_ENABLE_AUDIT_JOB, /* defaultValue= */ false)
                        || enabledForAllDomains();
                if (enabled) {
                    schedule();
                    mScheduler.schedule();
                } else {
                    mJobScheduler.cancel(SELINUX_AUDIT_JOB_ID);
                    mScheduler.cancel();
                }
            } else if (keyset.contains(CONFIG_SELINUX_AUDIT_JOB_FREQUENCY_HOURS)) {
                // The job frequency changed, reschedule.
                schedule();
                mScheduler.schedule();
            }
        }
    }

    private static final class SecurityPropertyMonitor
            implements DeviceConfig.OnPropertiesChangedListener {

        private final LogsCollectorJobScheduler mScheduler;

        private SecurityPropertyMonitor(LogsCollectorJobScheduler scheduler) {
            mScheduler = scheduler;
        }

        @Override
        public void onPropertiesChanged(Properties changedProperties) {
            Set<String> keyset = changedProperties.getKeyset();

            if (keyset.contains(CONFIG_SECURITY_SELINUX_AUDIT_JOB_ENABLED)) {
                boolean enabled =
                        changedProperties.getBoolean(
                                CONFIG_SECURITY_SELINUX_AUDIT_JOB_ENABLED,
                                /* defaultValue= */ false)
                        || enabledForSdkSandbox();
                if (enabled) {
                    mScheduler.schedule();
                } else {
                    mScheduler.cancel();
                }
            }
        }
    }

    /**
     * This class is in charge of scheduling the job service, and keeping the scheduling up to date
     * when the parameters change.
     */
    private static final class LogsCollectorJobScheduler {

        private final JobScheduler mJobScheduler;

        private LogsCollectorJobScheduler(JobScheduler jobScheduler) {
            mJobScheduler = jobScheduler;
        }

        public void cancel() {
            mJobScheduler.cancel(SELINUX_AUDIT_JOB_ID);
        }

        private void schedule() {
        public void schedule() {
            long frequencyMillis =
                    TimeUnit.HOURS.toMillis(
                            DeviceConfig.getInt(
+9 −0
Original line number Diff line number Diff line
package: "com.android.server.selinux.flags"
container: "system"

flag {
    name: "selinux_logs_collect"
    namespace: "network_security"
    description: "Enable collection of SELinux denials based on selinux_audit_job_enabled"
    bug: "372950125"
}