1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.seccomp.cts.app;
18 
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.Iterator;
22 
23 import android.content.Context;
24 import android.content.res.AssetManager;
25 import android.support.test.InstrumentationRegistry;
26 import android.support.test.runner.AndroidJUnit4;
27 import com.android.compatibility.common.util.CpuFeatures;
28 import org.json.JSONObject;
29 import org.json.JSONException;
30 
31 import org.junit.After;
32 import org.junit.Assert;
33 import org.junit.Assume;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 
38 /**
39  * Device-side tests for CtsSeccompHostTestCases
40  */
41 @RunWith(AndroidJUnit4.class)
42 public class SeccompDeviceTest {
43     static {
44         System.loadLibrary("ctsseccomp_jni");
45     }
46 
47     private JSONObject mAllowedSyscallMap;
48     private JSONObject mBlockedSyscallMap;
49 
50     @Before
initializeSyscallMap()51     public void initializeSyscallMap() throws IOException, JSONException {
52         final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
53         AssetManager manager = context.getAssets();
54         try (InputStream is = manager.open("syscalls_allowed.json")) {
55             mAllowedSyscallMap = new JSONObject(readInputStreamFully(is));
56         }
57         try (InputStream is = manager.open("syscalls_blocked.json")) {
58             mBlockedSyscallMap = new JSONObject(readInputStreamFully(is));
59         }
60     }
61 
62     @Test
testCTSSyscallAllowed()63     public void testCTSSyscallAllowed() throws JSONException {
64         JSONObject map = mAllowedSyscallMap.getJSONObject(getCurrentArch());
65         Iterator<String> iter = map.keys();
66         while (iter.hasNext()) {
67             String syscallName = iter.next();
68             testAllowed(map.getInt(syscallName));
69         }
70     }
71 
72     @Test
testCTSSyscallBlocked()73     public void testCTSSyscallBlocked() throws JSONException {
74         JSONObject map = mBlockedSyscallMap.getJSONObject(getCurrentArch());
75         Iterator<String> iter = map.keys();
76         while (iter.hasNext()) {
77             String syscallName = iter.next();
78             testBlocked(map.getInt(syscallName));
79         }
80     }
81 
getCurrentArch()82     private static String getCurrentArch() {
83         if (CpuFeatures.isArm64Cpu()) {
84             return "arm64";
85         } else if (CpuFeatures.isArmCpu()) {
86             return "arm";
87         } else if (CpuFeatures.isX86_64Cpu()) {
88             return "x86_64";
89         } else if (CpuFeatures.isX86Cpu()) {
90             return "x86";
91         } else if (CpuFeatures.isMips64Cpu()) {
92             return "mips64";
93         } else if (CpuFeatures.isMipsCpu()) {
94             return "mips";
95         } else {
96             Assert.fail("Unsupported OS");
97             return null;
98         }
99     }
100 
readInputStreamFully(InputStream is)101     private String readInputStreamFully(InputStream is) throws IOException {
102         StringBuilder sb = new StringBuilder();
103         byte[] buffer = new byte[4096];
104         while (is.available() > 0) {
105             int size = is.read(buffer);
106             if (size < 0) {
107                 break;
108             }
109             sb.append(new String(buffer, 0, size));
110         }
111         return sb.toString();
112     }
113 
testBlocked(int nr)114     private void testBlocked(int nr) {
115         Assert.assertTrue("Syscall " + nr + " not blocked", testSyscallBlocked(nr));
116     }
117 
testAllowed(int nr)118     private void testAllowed(int nr) {
119         Assert.assertFalse("Syscall " + nr + " blocked", testSyscallBlocked(nr));
120     }
121 
testSyscallBlocked(int nr)122     private static final native boolean testSyscallBlocked(int nr);
123 }
124