blob: 7e4ae2ccbf7244a4863454f5de9b75364d6d5f54 [file] [log] [blame]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.security.cts;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
import android.cts.host.utils.DeviceJUnit4Parameterized;
import android.platform.test.annotations.RestrictedBuildTest;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Neverallow Rules SELinux tests on vendor.
*
* This is a parametrised test. It extracts the neverallow rules from the
* platform policy which is embedded in the CTS distribution. Each rule
* generates its own test to ensure that it is not violated by the device
* policy.
*
* A set of criteria can be used in the platform policy to skip the test
* depending on the device (e.g., launching version). See
* SELinuxNeverallowRule.sConditions.
*
*/
@RunWith(DeviceJUnit4Parameterized.class)
@UseParametersRunnerFactory(DeviceJUnit4ClassRunnerWithParameters.RunnerFactory.class)
public class SELinuxNeverallowRulesTestVendor extends BaseHostJUnit4Test {
private File mSepolicyAnalyze;
private File mDeviceVendorPolicyFile;
private IBuildInfo mBuild;
private int mVendorSepolicyVersion = -1;
/**
* A reference to the device under test.
*/
private ITestDevice mDevice;
private static final Pattern VENDOR_POLICY_PATTERN = Pattern.compile(
"^([0-9]{6})_general_sepolicy.conf$");
/**
* Generate the test parameters based on the embedded policy ({ver}_general_sepolicy.conf).
*/
@Parameters(name = "ver={0,number,#};idx={1,number,#}")
public static Iterable<Object[]> generateRules() throws Exception {
List<Object[]> rules = new ArrayList<>();
JarFile jarFile = new JarFile(SELinuxHostTest.class
.getProtectionDomain()
.getCodeSource()
.getLocation()
.getPath());
jarFile.stream().forEach(entry -> {
try {
String name = entry.getName();
Matcher m = VENDOR_POLICY_PATTERN.matcher(name);
if (m.matches()) {
int ver = Integer.parseInt(m.group(1));
File publicPolicy = SELinuxHostTest.copyResourceToTempFile("/" + name);
String policy = Files.readString(publicPolicy.toPath());
List<SELinuxNeverallowRule> parsedRules =
SELinuxNeverallowRule.parsePolicy(policy);
for (int idx = 0; idx < parsedRules.size(); ++idx) {
rules.add(new Object[]{ver, idx, parsedRules.get(idx)});
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
});
jarFile.close();
assertTrue("No test generated from the CTS-embedded policy", !rules.isEmpty());
return rules;
}
@Parameter(0)
public int mVersion;
@Parameter(1)
public int mIndex;
/* Parameter generated by generateRules() and available to testNeverallowRules */
@Parameter(2)
public SELinuxNeverallowRule mRule;
@Before
public void setUp() throws Exception {
mDevice = getDevice();
mBuild = getBuild();
if (mVendorSepolicyVersion == -1) {
mVendorSepolicyVersion =
SELinuxHostTest.getVendorSepolicyVersion(mBuild, mDevice);
}
assumeTrue("skipping not matching vendor", mVendorSepolicyVersion == mVersion);
assumeTrue("skipping not compatible rule", mRule.isCompatible(mDevice));
if (mSepolicyAnalyze == null) {
mSepolicyAnalyze = SELinuxHostTest.copyResourceToTempFile("/sepolicy-analyze");
mSepolicyAnalyze.setExecutable(true);
}
mDeviceVendorPolicyFile = SELinuxHostTest.getDeviceVendorPolicyFile(mBuild, mDevice);
}
@After
public void tearDown() throws Exception {
if (mSepolicyAnalyze != null) {
mSepolicyAnalyze.delete();
mSepolicyAnalyze = null;
}
}
@Test
@RestrictedBuildTest
public void testNeverallowRules() throws Exception {
mRule.testNeverallowRule(mSepolicyAnalyze, mDeviceVendorPolicyFile);
}
}