xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/testcases/policy.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li // Copyright 2019 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li //     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li 
15*ec63e07aSXin Li // A binary that tries x86_64 compat syscalls, ptrace and clone untraced.
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <sched.h>
18*ec63e07aSXin Li #include <sys/ptrace.h>
19*ec63e07aSXin Li #include <syscall.h>
20*ec63e07aSXin Li #include <unistd.h>
21*ec63e07aSXin Li 
22*ec63e07aSXin Li #include <cerrno>
23*ec63e07aSXin Li #include <cstdint>
24*ec63e07aSXin Li #include <cstdio>
25*ec63e07aSXin Li #include <cstdlib>
26*ec63e07aSXin Li 
27*ec63e07aSXin Li #include "absl/base/attributes.h"
28*ec63e07aSXin Li #include "sandboxed_api/config.h"
29*ec63e07aSXin Li 
30*ec63e07aSXin Li #ifdef SAPI_X86_64
TestAMD64SyscallMismatch()31*ec63e07aSXin Li void TestAMD64SyscallMismatch() {
32*ec63e07aSXin Li   int64_t result;
33*ec63e07aSXin Li 
34*ec63e07aSXin Li   // exit() is allowed, but not if called via 32-bit syscall.
35*ec63e07aSXin Li   asm("movq $1, %%rax\n"   // __NR_exit: 1 in 32-bit (60 in 64-bit)
36*ec63e07aSXin Li       "movq $42, %%rbx\n"  // int error_code: 42
37*ec63e07aSXin Li       "int $0x80\n"
38*ec63e07aSXin Li       "movq %%rax, %0\n"
39*ec63e07aSXin Li       : "=r"(result)
40*ec63e07aSXin Li       :
41*ec63e07aSXin Li       : "rax", "rbx");
42*ec63e07aSXin Li   exit(-result);
43*ec63e07aSXin Li }
44*ec63e07aSXin Li 
TestAMD64SyscallMismatchFs()45*ec63e07aSXin Li void TestAMD64SyscallMismatchFs() {
46*ec63e07aSXin Li   int64_t result;
47*ec63e07aSXin Li   char filename[] = "/etc/passwd";
48*ec63e07aSXin Li 
49*ec63e07aSXin Li   // access("/etc/passwd") is allowed, but not if called via 32-bit syscall.
50*ec63e07aSXin Li   asm("movq $33, %%rax\n"  // __NR_access: 33 in 32-bit (21 in 64-bit)
51*ec63e07aSXin Li       "movq %1, %%rbx\n"   // const char* filename: /etc/passwd
52*ec63e07aSXin Li       "movq $0, %%rcx\n"   // int mode: F_OK (0), test for existence
53*ec63e07aSXin Li       "int $0x80\n"
54*ec63e07aSXin Li       "movq %%rax, %0\n"
55*ec63e07aSXin Li       : "=r"(result)
56*ec63e07aSXin Li       : "g"(filename)
57*ec63e07aSXin Li       : "rax", "rbx", "rcx");
58*ec63e07aSXin Li   exit(-result);
59*ec63e07aSXin Li }
60*ec63e07aSXin Li #endif
61*ec63e07aSXin Li 
TestPtraceDenied()62*ec63e07aSXin Li void TestPtraceDenied() {
63*ec63e07aSXin Li   ptrace(PTRACE_SEIZE, getppid(), 0, 0);
64*ec63e07aSXin Li 
65*ec63e07aSXin Li   printf("Syscall violation should have been discovered by now\n");
66*ec63e07aSXin Li   exit(EXIT_FAILURE);
67*ec63e07aSXin Li }
68*ec63e07aSXin Li 
TestPtraceBlocked()69*ec63e07aSXin Li void TestPtraceBlocked() {
70*ec63e07aSXin Li   int result = ptrace(PTRACE_SEIZE, getppid(), 0, 0);
71*ec63e07aSXin Li 
72*ec63e07aSXin Li   if (result != -1 || errno != EPERM) {
73*ec63e07aSXin Li     printf("System call should have been blocked\n");
74*ec63e07aSXin Li     exit(EXIT_FAILURE);
75*ec63e07aSXin Li   }
76*ec63e07aSXin Li }
77*ec63e07aSXin Li 
TestBpfBlocked()78*ec63e07aSXin Li void TestBpfBlocked() {
79*ec63e07aSXin Li   int result = syscall(__NR_bpf, 0, nullptr, 0);
80*ec63e07aSXin Li 
81*ec63e07aSXin Li   if (result != -1 || errno != EPERM) {
82*ec63e07aSXin Li     printf("System call should have been blocked\n");
83*ec63e07aSXin Li     exit(EXIT_FAILURE);
84*ec63e07aSXin Li   }
85*ec63e07aSXin Li }
86*ec63e07aSXin Li 
TestCloneUntraced()87*ec63e07aSXin Li void TestCloneUntraced() {
88*ec63e07aSXin Li   syscall(__NR_clone, static_cast<uintptr_t>(CLONE_UNTRACED), nullptr, nullptr,
89*ec63e07aSXin Li           nullptr, static_cast<uintptr_t>(0));
90*ec63e07aSXin Li 
91*ec63e07aSXin Li   printf("Syscall violation should have been discovered by now\n");
92*ec63e07aSXin Li   exit(EXIT_FAILURE);
93*ec63e07aSXin Li }
94*ec63e07aSXin Li 
TestBpf()95*ec63e07aSXin Li void TestBpf() {
96*ec63e07aSXin Li   syscall(__NR_bpf, 0, nullptr, 0);
97*ec63e07aSXin Li 
98*ec63e07aSXin Li   printf("Syscall violation should have been discovered by now\n");
99*ec63e07aSXin Li   exit(EXIT_FAILURE);
100*ec63e07aSXin Li }
101*ec63e07aSXin Li 
TestIsatty()102*ec63e07aSXin Li void TestIsatty() { isatty(0); }
103*ec63e07aSXin Li 
main(int argc,char * argv[])104*ec63e07aSXin Li int main(int argc, char* argv[]) {
105*ec63e07aSXin Li   // Disable buffering.
106*ec63e07aSXin Li   setbuf(stdin, nullptr);
107*ec63e07aSXin Li   setbuf(stdout, nullptr);
108*ec63e07aSXin Li   setbuf(stderr, nullptr);
109*ec63e07aSXin Li 
110*ec63e07aSXin Li   if (argc < 2) {
111*ec63e07aSXin Li     printf("argc < 3\n");
112*ec63e07aSXin Li     return EXIT_FAILURE;
113*ec63e07aSXin Li   }
114*ec63e07aSXin Li 
115*ec63e07aSXin Li   int testno = atoi(argv[1]);  // NOLINT
116*ec63e07aSXin Li   switch (testno) {
117*ec63e07aSXin Li #ifdef SAPI_X86_64
118*ec63e07aSXin Li     case 1:
119*ec63e07aSXin Li       TestAMD64SyscallMismatch();
120*ec63e07aSXin Li       break;
121*ec63e07aSXin Li     case 2:
122*ec63e07aSXin Li       TestAMD64SyscallMismatchFs();
123*ec63e07aSXin Li       break;
124*ec63e07aSXin Li #endif
125*ec63e07aSXin Li     case 3:
126*ec63e07aSXin Li       TestPtraceDenied();
127*ec63e07aSXin Li       break;
128*ec63e07aSXin Li     case 4:
129*ec63e07aSXin Li       TestCloneUntraced();
130*ec63e07aSXin Li       break;
131*ec63e07aSXin Li     case 5:
132*ec63e07aSXin Li       TestBpf();
133*ec63e07aSXin Li       break;
134*ec63e07aSXin Li     case 6:
135*ec63e07aSXin Li       TestIsatty();
136*ec63e07aSXin Li       break;
137*ec63e07aSXin Li     case 7:
138*ec63e07aSXin Li       TestPtraceBlocked();
139*ec63e07aSXin Li       ABSL_FALLTHROUGH_INTENDED;
140*ec63e07aSXin Li     case 8:
141*ec63e07aSXin Li       TestBpfBlocked();
142*ec63e07aSXin Li       break;
143*ec63e07aSXin Li     default:
144*ec63e07aSXin Li       printf("Unknown test: %d\n", testno);
145*ec63e07aSXin Li       return EXIT_FAILURE;
146*ec63e07aSXin Li   }
147*ec63e07aSXin Li 
148*ec63e07aSXin Li   printf("OK: All tests went OK\n");
149*ec63e07aSXin Li   return EXIT_SUCCESS;
150*ec63e07aSXin Li }
151