1#!/usr/bin/env python
2
3src_header = """/*
4 * Copyright (C) 2014 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19package android.cts.security;
20
21import android.platform.test.annotations.RestrictedBuildTest;
22import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
23import com.android.tradefed.build.IBuildInfo;
24import com.android.tradefed.device.ITestDevice;
25import com.android.tradefed.testtype.DeviceTestCase;
26import com.android.tradefed.testtype.IBuildReceiver;
27import com.android.tradefed.testtype.IDeviceTest;
28
29import java.io.BufferedReader;
30import java.io.File;
31import java.io.InputStream;
32import java.io.InputStreamReader;
33
34/**
35 * Neverallow Rules SELinux tests.
36 */
37public class SELinuxNeverallowRulesTest extends DeviceTestCase implements IBuildReceiver, IDeviceTest {
38    private static final int P_SEPOLICY_VERSION = 28;
39    private File sepolicyAnalyze;
40    private File devicePolicyFile;
41    private File deviceSystemPolicyFile;
42
43    private IBuildInfo mBuild;
44    private int mVendorSepolicyVersion = -1;
45
46    /**
47     * A reference to the device under test.
48     */
49    private ITestDevice mDevice;
50
51    /**
52     * {@inheritDoc}
53     */
54    @Override
55    public void setBuild(IBuildInfo build) {
56        mBuild = build;
57    }
58
59    /**
60     * {@inheritDoc}
61     */
62    @Override
63    public void setDevice(ITestDevice device) {
64        super.setDevice(device);
65        mDevice = device;
66    }
67    @Override
68    protected void setUp() throws Exception {
69        super.setUp();
70        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild);
71        sepolicyAnalyze = buildHelper.getTestFile("sepolicy-analyze");
72        sepolicyAnalyze.setExecutable(true);
73
74        devicePolicyFile = android.security.cts.SELinuxHostTest.getDevicePolicyFile(mDevice);
75
76        if (isSepolicySplit()) {
77            deviceSystemPolicyFile =
78                    android.security.cts.SELinuxHostTest.getDeviceSystemPolicyFile(mDevice);
79
80            // Caching this variable to save time.
81            if (mVendorSepolicyVersion == -1) {
82                mVendorSepolicyVersion =
83                        android.security.cts.SELinuxHostTest.getVendorSepolicyVersion(mDevice);
84            }
85        }
86    }
87
88    private boolean isFullTrebleDevice() throws Exception {
89        return android.security.cts.SELinuxHostTest.isFullTrebleDevice(mDevice);
90    }
91
92    private boolean isCompatiblePropertyEnforcedDevice() throws Exception {
93        return android.security.cts.SELinuxHostTest.isCompatiblePropertyEnforcedDevice(mDevice);
94    }
95
96    private boolean isSepolicySplit() throws Exception {
97        return android.security.cts.SELinuxHostTest.isSepolicySplit(mDevice);
98    }
99"""
100src_body = ""
101src_footer = """}
102"""
103
104src_method = """
105    @RestrictedBuildTest
106    public void testNeverallowRules() throws Exception {
107        String neverallowRule = "$NEVERALLOW_RULE_HERE$";
108        boolean fullTrebleOnly = $FULL_TREBLE_ONLY_BOOL_HERE$;
109        boolean compatiblePropertyOnly = $COMPATIBLE_PROPERTY_ONLY_BOOL_HERE$;
110
111        if ((fullTrebleOnly) && (!isFullTrebleDevice())) {
112            // This test applies only to Treble devices but this device isn't one
113            return;
114        }
115        if ((compatiblePropertyOnly) && (!isCompatiblePropertyEnforcedDevice())) {
116            // This test applies only to devices on which compatible property is enforced but this
117            // device isn't one
118            return;
119        }
120
121        // If sepolicy is split and vendor sepolicy version is behind platform's,
122        // only test against platform policy.
123        File policyFile =
124                (isSepolicySplit() && mVendorSepolicyVersion < P_SEPOLICY_VERSION) ?
125                deviceSystemPolicyFile :
126                devicePolicyFile;
127
128        /* run sepolicy-analyze neverallow check on policy file using given neverallow rules */
129        ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
130                policyFile.getAbsolutePath(), "neverallow", "-w", "-n",
131                neverallowRule);
132        pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
133        pb.redirectErrorStream(true);
134        Process p = pb.start();
135        p.waitFor();
136        BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
137        String line;
138        StringBuilder errorString = new StringBuilder();
139        while ((line = result.readLine()) != null) {
140            errorString.append(line);
141            errorString.append("\\n");
142        }
143        assertTrue("The following errors were encountered when validating the SELinux"
144                   + "neverallow rule:\\n" + neverallowRule + "\\n" + errorString,
145                   errorString.length() == 0);
146    }
147"""
148