Loading services/core/java/com/android/server/selinux/SelinuxAuditLogBuilder.java +2 −10 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ */ package com.android.server.selinux; import android.provider.DeviceConfig; import android.text.TextUtils; import android.util.Slog; Loading @@ -34,10 +33,6 @@ class SelinuxAuditLogBuilder { private static final String TAG = "SelinuxAuditLogs"; // This config indicates which Selinux logs for source domains to collect. The string will be // inserted into a regex, so it must follow the regex syntax. For example, a valid value would // be "system_server|untrusted_app". @VisibleForTesting static final String CONFIG_SELINUX_AUDIT_DOMAIN = "selinux_audit_domain"; private static final Matcher NO_OP_MATCHER = Pattern.compile("no-op^").matcher(""); private static final String TCONTEXT_PATTERN = "u:object_r:(?<ttype>\\w+):s0(:c)?(?<tcategories>((,c)?\\d+)+)*"; Loading @@ -50,7 +45,7 @@ class SelinuxAuditLogBuilder { private Iterator<String> mTokens; private final SelinuxAuditLog mAuditLog = new SelinuxAuditLog(); SelinuxAuditLogBuilder() { SelinuxAuditLogBuilder(String auditDomain) { Matcher scontextMatcher = NO_OP_MATCHER; Matcher tcontextMatcher = NO_OP_MATCHER; Matcher pathMatcher = NO_OP_MATCHER; Loading @@ -59,10 +54,7 @@ class SelinuxAuditLogBuilder { Pattern.compile( TextUtils.formatSimple( "u:r:(?<stype>%s):s0(:c)?(?<scategories>((,c)?\\d+)+)*", DeviceConfig.getString( DeviceConfig.NAMESPACE_ADSERVICES, CONFIG_SELINUX_AUDIT_DOMAIN, "no_match^"))) auditDomain)) .matcher(""); tcontextMatcher = Pattern.compile(TCONTEXT_PATTERN).matcher(""); pathMatcher = Pattern.compile(PATH_PATTERN).matcher(""); Loading services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java +27 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.server.selinux; import android.provider.DeviceConfig; import android.util.EventLog; import android.util.EventLog.Event; import android.util.Log; Loading @@ -32,6 +33,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Queue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading @@ -43,9 +45,16 @@ class SelinuxAuditLogsCollector { private static final String SELINUX_PATTERN = "^.*\\bavc:\\s+(?<denial>.*)$"; // This config indicates which Selinux logs for source domains to collect. The string will be // inserted into a regex, so it must follow the regex syntax. For example, a valid value would // be "system_server|untrusted_app". @VisibleForTesting static final String CONFIG_SELINUX_AUDIT_DOMAIN = "selinux_audit_domain"; @VisibleForTesting static final String DEFAULT_SELINUX_AUDIT_DOMAIN = "no_match^"; @VisibleForTesting static final Matcher SELINUX_MATCHER = Pattern.compile(SELINUX_PATTERN).matcher(""); private final Supplier<String> mAuditDomainSupplier; private final RateLimiter mRateLimiter; private final QuotaLimiter mQuotaLimiter; Loading @@ -53,11 +62,26 @@ class SelinuxAuditLogsCollector { AtomicBoolean mStopRequested = new AtomicBoolean(false); SelinuxAuditLogsCollector(RateLimiter rateLimiter, QuotaLimiter quotaLimiter) { SelinuxAuditLogsCollector( Supplier<String> auditDomainSupplier, RateLimiter rateLimiter, QuotaLimiter quotaLimiter) { mAuditDomainSupplier = auditDomainSupplier; mRateLimiter = rateLimiter; mQuotaLimiter = quotaLimiter; } SelinuxAuditLogsCollector(RateLimiter rateLimiter, QuotaLimiter quotaLimiter) { this( () -> DeviceConfig.getString( DeviceConfig.NAMESPACE_ADSERVICES, CONFIG_SELINUX_AUDIT_DOMAIN, DEFAULT_SELINUX_AUDIT_DOMAIN), rateLimiter, quotaLimiter); } public void setStopRequested(boolean stopRequested) { mStopRequested.set(stopRequested); } Loading Loading @@ -108,7 +132,8 @@ class SelinuxAuditLogsCollector { } private boolean writeAuditLogs(Queue<Event> logLines) { final SelinuxAuditLogBuilder auditLogBuilder = new SelinuxAuditLogBuilder(); final SelinuxAuditLogBuilder auditLogBuilder = new SelinuxAuditLogBuilder(mAuditDomainSupplier.get()); int auditsWritten = 0; while (!mStopRequested.get() && !logLines.isEmpty()) { Loading services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsBuilderTest.java +5 −31 Original line number Diff line number Diff line Loading @@ -15,18 +15,14 @@ */ package com.android.server.selinux; import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import static com.android.server.selinux.SelinuxAuditLogBuilder.toCategories; import static com.google.common.truth.Truth.assertThat; import android.provider.DeviceConfig; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.server.selinux.SelinuxAuditLogBuilder.SelinuxAuditLog; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -45,24 +41,12 @@ public class SelinuxAuditLogsBuilderTest { @Before public void setUp() { runWithShellPermissionIdentity( () -> DeviceConfig.setLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN, TEST_DOMAIN)); mAuditLogBuilder = new SelinuxAuditLogBuilder(); mAuditLogBuilder = new SelinuxAuditLogBuilder(TEST_DOMAIN); mScontextMatcher = mAuditLogBuilder.mScontextMatcher; mTcontextMatcher = mAuditLogBuilder.mTcontextMatcher; mPathMatcher = mAuditLogBuilder.mPathMatcher; } @After public void tearDown() { runWithShellPermissionIdentity(() -> DeviceConfig.clearAllLocalOverrides()); } @Test public void testMatcher_scontext() { assertThat(mScontextMatcher.reset("u:r:" + TEST_DOMAIN + ":s0").matches()).isTrue(); Loading Loading @@ -109,13 +93,9 @@ public class SelinuxAuditLogsBuilderTest { @Test public void testMatcher_scontextDefaultConfig() { runWithShellPermissionIdentity( () -> DeviceConfig.clearLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN)); Matcher scontexMatcher = new SelinuxAuditLogBuilder().mScontextMatcher; Matcher scontexMatcher = new SelinuxAuditLogBuilder(SelinuxAuditLogsCollector.DEFAULT_SELINUX_AUDIT_DOMAIN) .mScontextMatcher; assertThat(scontexMatcher.reset("u:r:" + TEST_DOMAIN + ":s0").matches()).isFalse(); assertThat(scontexMatcher.reset("u:r:" + TEST_DOMAIN + ":s0:c123,c456").matches()) Loading Loading @@ -221,13 +201,7 @@ public class SelinuxAuditLogsBuilderTest { @Test public void testSelinuxAuditLogsBuilder_wrongConfig() { String notARegexDomain = "not]a[regex"; runWithShellPermissionIdentity( () -> DeviceConfig.setLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN, notARegexDomain)); SelinuxAuditLogBuilder noOpBuilder = new SelinuxAuditLogBuilder(); SelinuxAuditLogBuilder noOpBuilder = new SelinuxAuditLogBuilder(notARegexDomain); noOpBuilder.reset( "granted { p } scontext=u:r:" Loading services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java +1 −10 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ */ package com.android.server.selinux; import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; Loading @@ -28,7 +27,6 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import android.provider.DeviceConfig; import android.util.EventLog; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading Loading @@ -59,6 +57,7 @@ public class SelinuxAuditLogsCollectorTest { private final SelinuxAuditLogsCollector mSelinuxAutidLogsCollector = // Ignore rate limiting for tests new SelinuxAuditLogsCollector( () -> TEST_DOMAIN, new RateLimiter(mClock, /* window= */ Duration.ofMillis(0)), new QuotaLimiter( mClock, /* windowSize= */ Duration.ofHours(1), /* maxPermits= */ 5)); Loading @@ -67,13 +66,6 @@ public class SelinuxAuditLogsCollectorTest { @Before public void setUp() { runWithShellPermissionIdentity( () -> DeviceConfig.setLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN, TEST_DOMAIN)); mSelinuxAutidLogsCollector.setStopRequested(false); // move the clock forward for the limiters. mClock.currentTimeMillis += Duration.ofHours(1).toMillis(); Loading @@ -85,7 +77,6 @@ public class SelinuxAuditLogsCollectorTest { @After public void tearDown() { runWithShellPermissionIdentity(() -> DeviceConfig.clearAllLocalOverrides()); mMockitoSession.finishMocking(); } Loading Loading
services/core/java/com/android/server/selinux/SelinuxAuditLogBuilder.java +2 −10 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ */ package com.android.server.selinux; import android.provider.DeviceConfig; import android.text.TextUtils; import android.util.Slog; Loading @@ -34,10 +33,6 @@ class SelinuxAuditLogBuilder { private static final String TAG = "SelinuxAuditLogs"; // This config indicates which Selinux logs for source domains to collect. The string will be // inserted into a regex, so it must follow the regex syntax. For example, a valid value would // be "system_server|untrusted_app". @VisibleForTesting static final String CONFIG_SELINUX_AUDIT_DOMAIN = "selinux_audit_domain"; private static final Matcher NO_OP_MATCHER = Pattern.compile("no-op^").matcher(""); private static final String TCONTEXT_PATTERN = "u:object_r:(?<ttype>\\w+):s0(:c)?(?<tcategories>((,c)?\\d+)+)*"; Loading @@ -50,7 +45,7 @@ class SelinuxAuditLogBuilder { private Iterator<String> mTokens; private final SelinuxAuditLog mAuditLog = new SelinuxAuditLog(); SelinuxAuditLogBuilder() { SelinuxAuditLogBuilder(String auditDomain) { Matcher scontextMatcher = NO_OP_MATCHER; Matcher tcontextMatcher = NO_OP_MATCHER; Matcher pathMatcher = NO_OP_MATCHER; Loading @@ -59,10 +54,7 @@ class SelinuxAuditLogBuilder { Pattern.compile( TextUtils.formatSimple( "u:r:(?<stype>%s):s0(:c)?(?<scategories>((,c)?\\d+)+)*", DeviceConfig.getString( DeviceConfig.NAMESPACE_ADSERVICES, CONFIG_SELINUX_AUDIT_DOMAIN, "no_match^"))) auditDomain)) .matcher(""); tcontextMatcher = Pattern.compile(TCONTEXT_PATTERN).matcher(""); pathMatcher = Pattern.compile(PATH_PATTERN).matcher(""); Loading
services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java +27 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.server.selinux; import android.provider.DeviceConfig; import android.util.EventLog; import android.util.EventLog.Event; import android.util.Log; Loading @@ -32,6 +33,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Queue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading @@ -43,9 +45,16 @@ class SelinuxAuditLogsCollector { private static final String SELINUX_PATTERN = "^.*\\bavc:\\s+(?<denial>.*)$"; // This config indicates which Selinux logs for source domains to collect. The string will be // inserted into a regex, so it must follow the regex syntax. For example, a valid value would // be "system_server|untrusted_app". @VisibleForTesting static final String CONFIG_SELINUX_AUDIT_DOMAIN = "selinux_audit_domain"; @VisibleForTesting static final String DEFAULT_SELINUX_AUDIT_DOMAIN = "no_match^"; @VisibleForTesting static final Matcher SELINUX_MATCHER = Pattern.compile(SELINUX_PATTERN).matcher(""); private final Supplier<String> mAuditDomainSupplier; private final RateLimiter mRateLimiter; private final QuotaLimiter mQuotaLimiter; Loading @@ -53,11 +62,26 @@ class SelinuxAuditLogsCollector { AtomicBoolean mStopRequested = new AtomicBoolean(false); SelinuxAuditLogsCollector(RateLimiter rateLimiter, QuotaLimiter quotaLimiter) { SelinuxAuditLogsCollector( Supplier<String> auditDomainSupplier, RateLimiter rateLimiter, QuotaLimiter quotaLimiter) { mAuditDomainSupplier = auditDomainSupplier; mRateLimiter = rateLimiter; mQuotaLimiter = quotaLimiter; } SelinuxAuditLogsCollector(RateLimiter rateLimiter, QuotaLimiter quotaLimiter) { this( () -> DeviceConfig.getString( DeviceConfig.NAMESPACE_ADSERVICES, CONFIG_SELINUX_AUDIT_DOMAIN, DEFAULT_SELINUX_AUDIT_DOMAIN), rateLimiter, quotaLimiter); } public void setStopRequested(boolean stopRequested) { mStopRequested.set(stopRequested); } Loading Loading @@ -108,7 +132,8 @@ class SelinuxAuditLogsCollector { } private boolean writeAuditLogs(Queue<Event> logLines) { final SelinuxAuditLogBuilder auditLogBuilder = new SelinuxAuditLogBuilder(); final SelinuxAuditLogBuilder auditLogBuilder = new SelinuxAuditLogBuilder(mAuditDomainSupplier.get()); int auditsWritten = 0; while (!mStopRequested.get() && !logLines.isEmpty()) { Loading
services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsBuilderTest.java +5 −31 Original line number Diff line number Diff line Loading @@ -15,18 +15,14 @@ */ package com.android.server.selinux; import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import static com.android.server.selinux.SelinuxAuditLogBuilder.toCategories; import static com.google.common.truth.Truth.assertThat; import android.provider.DeviceConfig; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.server.selinux.SelinuxAuditLogBuilder.SelinuxAuditLog; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -45,24 +41,12 @@ public class SelinuxAuditLogsBuilderTest { @Before public void setUp() { runWithShellPermissionIdentity( () -> DeviceConfig.setLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN, TEST_DOMAIN)); mAuditLogBuilder = new SelinuxAuditLogBuilder(); mAuditLogBuilder = new SelinuxAuditLogBuilder(TEST_DOMAIN); mScontextMatcher = mAuditLogBuilder.mScontextMatcher; mTcontextMatcher = mAuditLogBuilder.mTcontextMatcher; mPathMatcher = mAuditLogBuilder.mPathMatcher; } @After public void tearDown() { runWithShellPermissionIdentity(() -> DeviceConfig.clearAllLocalOverrides()); } @Test public void testMatcher_scontext() { assertThat(mScontextMatcher.reset("u:r:" + TEST_DOMAIN + ":s0").matches()).isTrue(); Loading Loading @@ -109,13 +93,9 @@ public class SelinuxAuditLogsBuilderTest { @Test public void testMatcher_scontextDefaultConfig() { runWithShellPermissionIdentity( () -> DeviceConfig.clearLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN)); Matcher scontexMatcher = new SelinuxAuditLogBuilder().mScontextMatcher; Matcher scontexMatcher = new SelinuxAuditLogBuilder(SelinuxAuditLogsCollector.DEFAULT_SELINUX_AUDIT_DOMAIN) .mScontextMatcher; assertThat(scontexMatcher.reset("u:r:" + TEST_DOMAIN + ":s0").matches()).isFalse(); assertThat(scontexMatcher.reset("u:r:" + TEST_DOMAIN + ":s0:c123,c456").matches()) Loading Loading @@ -221,13 +201,7 @@ public class SelinuxAuditLogsBuilderTest { @Test public void testSelinuxAuditLogsBuilder_wrongConfig() { String notARegexDomain = "not]a[regex"; runWithShellPermissionIdentity( () -> DeviceConfig.setLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN, notARegexDomain)); SelinuxAuditLogBuilder noOpBuilder = new SelinuxAuditLogBuilder(); SelinuxAuditLogBuilder noOpBuilder = new SelinuxAuditLogBuilder(notARegexDomain); noOpBuilder.reset( "granted { p } scontext=u:r:" Loading
services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java +1 −10 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ */ package com.android.server.selinux; import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; Loading @@ -28,7 +27,6 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import android.provider.DeviceConfig; import android.util.EventLog; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading Loading @@ -59,6 +57,7 @@ public class SelinuxAuditLogsCollectorTest { private final SelinuxAuditLogsCollector mSelinuxAutidLogsCollector = // Ignore rate limiting for tests new SelinuxAuditLogsCollector( () -> TEST_DOMAIN, new RateLimiter(mClock, /* window= */ Duration.ofMillis(0)), new QuotaLimiter( mClock, /* windowSize= */ Duration.ofHours(1), /* maxPermits= */ 5)); Loading @@ -67,13 +66,6 @@ public class SelinuxAuditLogsCollectorTest { @Before public void setUp() { runWithShellPermissionIdentity( () -> DeviceConfig.setLocalOverride( DeviceConfig.NAMESPACE_ADSERVICES, SelinuxAuditLogBuilder.CONFIG_SELINUX_AUDIT_DOMAIN, TEST_DOMAIN)); mSelinuxAutidLogsCollector.setStopRequested(false); // move the clock forward for the limiters. mClock.currentTimeMillis += Duration.ofHours(1).toMillis(); Loading @@ -85,7 +77,6 @@ public class SelinuxAuditLogsCollectorTest { @After public void tearDown() { runWithShellPermissionIdentity(() -> DeviceConfig.clearAllLocalOverrides()); mMockitoSession.finishMocking(); } Loading