| #!/usr/bin/env python |
| |
| src_header = """/* |
| * Copyright (C) 2014 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 android.platform.test.annotations.RestrictedBuildTest; |
| import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; |
| import com.android.compatibility.common.util.PropertyUtil; |
| import com.android.tradefed.build.IBuildInfo; |
| import com.android.tradefed.device.ITestDevice; |
| import com.android.tradefed.testtype.DeviceTestCase; |
| import com.android.tradefed.testtype.IBuildReceiver; |
| import com.android.tradefed.testtype.IDeviceTest; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| |
| /** |
| * Neverallow Rules SELinux tests. |
| */ |
| public class SELinuxNeverallowRulesTest extends DeviceTestCase implements IBuildReceiver, IDeviceTest { |
| private static final int Q_SEPOLICY_VERSION = 29; |
| private File sepolicyAnalyze; |
| private File devicePolicyFile; |
| private File deviceSystemPolicyFile; |
| |
| private IBuildInfo mBuild; |
| private int mVendorSepolicyVersion = -1; |
| |
| /** |
| * A reference to the device under test. |
| */ |
| private ITestDevice mDevice; |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void setBuild(IBuildInfo build) { |
| mBuild = build; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void setDevice(ITestDevice device) { |
| super.setDevice(device); |
| mDevice = device; |
| } |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild); |
| sepolicyAnalyze = android.security.cts.SELinuxHostTest.copyResourceToTempFile("/sepolicy-analyze"); |
| sepolicyAnalyze.setExecutable(true); |
| |
| devicePolicyFile = android.security.cts.SELinuxHostTest.getDevicePolicyFile(mDevice); |
| |
| if (isSepolicySplit()) { |
| deviceSystemPolicyFile = |
| android.security.cts.SELinuxHostTest.getDeviceSystemPolicyFile(mDevice); |
| |
| // Caching this variable to save time. |
| if (mVendorSepolicyVersion == -1) { |
| mVendorSepolicyVersion = |
| android.security.cts.SELinuxHostTest.getVendorSepolicyVersion(mDevice); |
| } |
| } |
| } |
| |
| private boolean isFullTrebleDevice() throws Exception { |
| return android.security.cts.SELinuxHostTest.isFullTrebleDevice(mDevice); |
| } |
| |
| private boolean isDeviceLaunchingWithR() throws Exception { |
| return PropertyUtil.getFirstApiLevel(mDevice) > 29; |
| } |
| |
| private boolean isCompatiblePropertyEnforcedDevice() throws Exception { |
| return android.security.cts.SELinuxHostTest.isCompatiblePropertyEnforcedDevice(mDevice); |
| } |
| |
| private boolean isSepolicySplit() throws Exception { |
| return android.security.cts.SELinuxHostTest.isSepolicySplit(mDevice); |
| } |
| """ |
| src_body = "" |
| src_footer = """} |
| """ |
| |
| src_method = """ |
| @RestrictedBuildTest |
| public void testNeverallowRules() throws Exception { |
| String neverallowRule = "$NEVERALLOW_RULE_HERE$"; |
| boolean fullTrebleOnly = $TREBLE_ONLY_BOOL_HERE$; |
| boolean launchingWithROnly = $LAUNCHING_WITH_R_ONLY_BOOL_HERE$; |
| boolean compatiblePropertyOnly = $COMPATIBLE_PROPERTY_ONLY_BOOL_HERE$; |
| |
| if ((fullTrebleOnly) && (!isFullTrebleDevice())) { |
| // This test applies only to Treble devices but this device isn't one |
| return; |
| } |
| if ((launchingWithROnly) && (!isDeviceLaunchingWithR())) { |
| // This test applies only to devices launching with R or later but this device isn't one |
| return; |
| } |
| if ((compatiblePropertyOnly) && (!isCompatiblePropertyEnforcedDevice())) { |
| // This test applies only to devices on which compatible property is enforced but this |
| // device isn't one |
| return; |
| } |
| |
| // If sepolicy is split and vendor sepolicy version is behind platform's, |
| // only test against platform policy. |
| File policyFile = |
| (isSepolicySplit() && mVendorSepolicyVersion < Q_SEPOLICY_VERSION) ? |
| deviceSystemPolicyFile : |
| devicePolicyFile; |
| |
| /* run sepolicy-analyze neverallow check on policy file using given neverallow rules */ |
| ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(), |
| policyFile.getAbsolutePath(), "neverallow", "-w", "-n", |
| neverallowRule); |
| pb.redirectOutput(ProcessBuilder.Redirect.PIPE); |
| pb.redirectErrorStream(true); |
| Process p = pb.start(); |
| p.waitFor(); |
| BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream())); |
| String line; |
| StringBuilder errorString = new StringBuilder(); |
| while ((line = result.readLine()) != null) { |
| errorString.append(line); |
| errorString.append("\\n"); |
| } |
| assertTrue("The following errors were encountered when validating the SELinux" |
| + "neverallow rule:\\n" + neverallowRule + "\\n" + errorString, |
| errorString.length() == 0); |
| } |
| """ |