1 /*
2  * Copyright (C) 2018 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 android.content.pm.ApplicationInfo;
20 import android.os.Process;
21 import android.util.Log;
22 
23 public class ZygotePreload implements android.app.ZygotePreload {
24     static final String TAG = "SeccompDeviceTest";
25 
26     static volatile boolean sResult = false;
27 
testSetResUidGidBlocked(int rid, int eid, int sid)28     static private boolean testSetResUidGidBlocked(int rid, int eid, int sid) {
29         if (!SeccompDeviceTest.testSetresuidBlocked(rid, eid, sid)) {
30             Log.e(TAG, "setresuid( " + Integer.toString(rid) + ","
31                     + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
32                     + " is wrongly allowed.");
33             return false;
34         }
35         if (!SeccompDeviceTest.testSetresgidBlocked(rid, eid, sid)) {
36             Log.e(TAG, "setresguid( " + Integer.toString(rid) + ","
37                     + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
38                     + " is wrongly allowed.");
39             return false;
40         }
41 
42         return true;
43     }
44 
testSetResUidGidAllowed(int rid, int eid, int sid)45     static private boolean testSetResUidGidAllowed(int rid, int eid, int sid) {
46         if (SeccompDeviceTest.testSetresuidBlocked(rid, eid, sid)) {
47             Log.e(TAG, "setresuid( " + Integer.toString(rid) + ","
48                     + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
49                     + " is wrongly blocked.");
50             return false;
51         }
52         if (SeccompDeviceTest.testSetresgidBlocked(rid, eid, sid)) {
53             Log.e(TAG, "setresguid( " + Integer.toString(rid) + ","
54                     + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
55                     + " is wrongly blocked.");
56             return false;
57         }
58 
59         return true;
60     }
61 
getSeccomptestResult()62     static synchronized public boolean getSeccomptestResult() {
63         return sResult;
64     }
65 
66     /*
67      * This is called from the app_zygote security context, which has two seccomp
68      * filters in place:
69      * 1) The regular app seccomp filter (which allows setresuid/setresgid)
70      * 2) A setresuid/setresgid limiting filter, which restricts the calls to
71      *    setresuid/setresgid to be in a particular range.
72      *
73      * This test enforces 2) is in place.
74      */
75     @Override
doPreload(ApplicationInfo appInfo)76     synchronized public void doPreload(ApplicationInfo appInfo) {
77         boolean result = true;
78 
79         // root uid
80         result &= testSetResUidGidBlocked(0, 0, 0);
81         // system uid
82         result &= testSetResUidGidBlocked(Process.SYSTEM_UID, Process.SYSTEM_UID,
83                 Process.SYSTEM_UID);
84         // mix of uids
85         result &= testSetResUidGidBlocked(0, Process.SYSTEM_UID,
86                 Process.SYSTEM_UID);
87 
88         // an app uid
89         result &= testSetResUidGidBlocked(Process.FIRST_APPLICATION_UID,
90                 Process.FIRST_APPLICATION_UID, Process.FIRST_APPLICATION_UID);
91         result &= testSetResUidGidBlocked(Process.LAST_APPLICATION_UID,
92                 Process.LAST_APPLICATION_UID, Process.LAST_APPLICATION_UID);
93 
94         // an isolated process uid
95         result &= testSetResUidGidBlocked(Process.FIRST_ISOLATED_UID,
96                 Process.FIRST_ISOLATED_UID, Process.FIRST_ISOLATED_UID);
97         result &= testSetResUidGidBlocked(Process.LAST_ISOLATED_UID, Process.LAST_ISOLATED_UID,
98                 Process.LAST_ISOLATED_UID);
99 
100         // an allowed app zygote UID
101         // TODO this test assumes no other isolated app zygotes are currently running!
102         result &= testSetResUidGidAllowed(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
103                 Process.FIRST_APP_ZYGOTE_ISOLATED_UID, Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
104 
105         // off-by-one
106         result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1,
107                 Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1,
108                 Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1);
109 
110         // mixed allowed rgid with dis-allowed euid and suid (and variants)
111         result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0, 0);
112         result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
113                 Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0);
114         result &= testSetResUidGidBlocked(0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0);
115         result &= testSetResUidGidBlocked(0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
116                 Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
117         result &= testSetResUidGidBlocked(0, 0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
118         result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0,
119                 Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
120 
121         // a disallowed app zygote UID
122         result &= testSetResUidGidBlocked(Process.LAST_APP_ZYGOTE_ISOLATED_UID,
123                 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.LAST_APP_ZYGOTE_ISOLATED_UID);
124 
125         // Store result
126         sResult = result;
127     }
128 }
129