xref: /aosp_15_r20/external/selinux/sandbox/test_sandbox.py (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Workerimport unittest
2*2d543d20SAndroid Build Coastguard Workerimport os
3*2d543d20SAndroid Build Coastguard Workerimport shutil
4*2d543d20SAndroid Build Coastguard Workerimport sys
5*2d543d20SAndroid Build Coastguard Workerfrom tempfile import mkdtemp
6*2d543d20SAndroid Build Coastguard Workerfrom subprocess import Popen, PIPE
7*2d543d20SAndroid Build Coastguard Worker
8*2d543d20SAndroid Build Coastguard Worker
9*2d543d20SAndroid Build Coastguard Workerclass SandboxTests(unittest.TestCase):
10*2d543d20SAndroid Build Coastguard Worker
11*2d543d20SAndroid Build Coastguard Worker    def assertDenied(self, err):
12*2d543d20SAndroid Build Coastguard Worker        self.assertTrue(b'Permission denied' in err,
13*2d543d20SAndroid Build Coastguard Worker                        '"Permission denied" not found in %r' % err)
14*2d543d20SAndroid Build Coastguard Worker
15*2d543d20SAndroid Build Coastguard Worker    def assertNotFound(self, err):
16*2d543d20SAndroid Build Coastguard Worker        self.assertTrue(b'not found' in err,
17*2d543d20SAndroid Build Coastguard Worker                        '"not found" not found in %r' % err)
18*2d543d20SAndroid Build Coastguard Worker
19*2d543d20SAndroid Build Coastguard Worker    def assertFailure(self, status):
20*2d543d20SAndroid Build Coastguard Worker        self.assertTrue(status != 0,
21*2d543d20SAndroid Build Coastguard Worker                        '"Succeeded when it should have failed')
22*2d543d20SAndroid Build Coastguard Worker
23*2d543d20SAndroid Build Coastguard Worker    def assertSuccess(self, status, err):
24*2d543d20SAndroid Build Coastguard Worker        self.assertTrue(status == 0,
25*2d543d20SAndroid Build Coastguard Worker                        '"Sandbox should have succeeded for this test %r' % err)
26*2d543d20SAndroid Build Coastguard Worker
27*2d543d20SAndroid Build Coastguard Worker    def test_simple_success(self):
28*2d543d20SAndroid Build Coastguard Worker        "Verify that we can read file descriptors handed to sandbox"
29*2d543d20SAndroid Build Coastguard Worker        p1 = Popen(['cat', '/etc/passwd'], stdout=PIPE)
30*2d543d20SAndroid Build Coastguard Worker        p2 = Popen([sys.executable, 'sandbox', 'grep', 'root'], stdin=p1.stdout, stdout=PIPE)
31*2d543d20SAndroid Build Coastguard Worker        p1.stdout.close()
32*2d543d20SAndroid Build Coastguard Worker        out, err = p2.communicate()
33*2d543d20SAndroid Build Coastguard Worker        self.assertTrue(b'root' in out)
34*2d543d20SAndroid Build Coastguard Worker
35*2d543d20SAndroid Build Coastguard Worker    def test_cant_kill(self):
36*2d543d20SAndroid Build Coastguard Worker        "Verify that we cannot send kill signal in the sandbox"
37*2d543d20SAndroid Build Coastguard Worker        pid = os.getpid()
38*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', 'kill', '-HUP', str(pid)], stdout=PIPE, stderr=PIPE)
39*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
40*2d543d20SAndroid Build Coastguard Worker        self.assertDenied(err)
41*2d543d20SAndroid Build Coastguard Worker
42*2d543d20SAndroid Build Coastguard Worker    def test_cant_ping(self):
43*2d543d20SAndroid Build Coastguard Worker        "Verify that we can't ping within the sandbox"
44*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', 'ping', '-c 1 ', '127.0.0.1'], stdout=PIPE, stderr=PIPE)
45*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
46*2d543d20SAndroid Build Coastguard Worker        self.assertDenied(err)
47*2d543d20SAndroid Build Coastguard Worker
48*2d543d20SAndroid Build Coastguard Worker    def test_cant_mkdir(self):
49*2d543d20SAndroid Build Coastguard Worker        "Verify that we can't mkdir within the sandbox"
50*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', 'mkdir', '~/test'], stdout=PIPE, stderr=PIPE)
51*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
52*2d543d20SAndroid Build Coastguard Worker        self.assertFailure(p.returncode)
53*2d543d20SAndroid Build Coastguard Worker
54*2d543d20SAndroid Build Coastguard Worker    def test_cant_list_homedir(self):
55*2d543d20SAndroid Build Coastguard Worker        "Verify that we can't list homedir within the sandbox"
56*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', 'ls', '~'], stdout=PIPE, stderr=PIPE)
57*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
58*2d543d20SAndroid Build Coastguard Worker        self.assertFailure(p.returncode)
59*2d543d20SAndroid Build Coastguard Worker
60*2d543d20SAndroid Build Coastguard Worker    def test_cant_send_mail(self):
61*2d543d20SAndroid Build Coastguard Worker        "Verify that we can't send mail within the sandbox"
62*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', 'mail'], stdout=PIPE, stderr=PIPE)
63*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
64*2d543d20SAndroid Build Coastguard Worker        self.assertDenied(err)
65*2d543d20SAndroid Build Coastguard Worker
66*2d543d20SAndroid Build Coastguard Worker    def test_cant_sudo(self):
67*2d543d20SAndroid Build Coastguard Worker        "Verify that we can't run sudo within the sandbox"
68*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', 'sudo'], stdout=PIPE, stderr=PIPE)
69*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
70*2d543d20SAndroid Build Coastguard Worker        self.assertFailure(p.returncode)
71*2d543d20SAndroid Build Coastguard Worker
72*2d543d20SAndroid Build Coastguard Worker    def test_mount(self):
73*2d543d20SAndroid Build Coastguard Worker        "Verify that we mount a file system"
74*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', '-M', 'id'], stdout=PIPE, stderr=PIPE)
75*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
76*2d543d20SAndroid Build Coastguard Worker        self.assertSuccess(p.returncode, err)
77*2d543d20SAndroid Build Coastguard Worker
78*2d543d20SAndroid Build Coastguard Worker    def test_set_level(self):
79*2d543d20SAndroid Build Coastguard Worker        "Verify that we set level a file system"
80*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', '-l', 's0', 'id'], stdout=PIPE, stderr=PIPE)
81*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
82*2d543d20SAndroid Build Coastguard Worker        self.assertSuccess(p.returncode, err)
83*2d543d20SAndroid Build Coastguard Worker
84*2d543d20SAndroid Build Coastguard Worker    def test_homedir(self):
85*2d543d20SAndroid Build Coastguard Worker        "Verify that we set homedir a file system"
86*2d543d20SAndroid Build Coastguard Worker        homedir = mkdtemp(dir=".", prefix=".sandbox_test")
87*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', '-H', homedir, '-M', 'id'], stdout=PIPE, stderr=PIPE)
88*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
89*2d543d20SAndroid Build Coastguard Worker        shutil.rmtree(homedir)
90*2d543d20SAndroid Build Coastguard Worker        self.assertSuccess(p.returncode, err)
91*2d543d20SAndroid Build Coastguard Worker
92*2d543d20SAndroid Build Coastguard Worker    def test_tmpdir(self):
93*2d543d20SAndroid Build Coastguard Worker        "Verify that we set tmpdir a file system"
94*2d543d20SAndroid Build Coastguard Worker        tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_test")
95*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', '-T', tmpdir, '-M', 'id'], stdout=PIPE, stderr=PIPE)
96*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
97*2d543d20SAndroid Build Coastguard Worker        shutil.rmtree(tmpdir)
98*2d543d20SAndroid Build Coastguard Worker        self.assertSuccess(p.returncode, err)
99*2d543d20SAndroid Build Coastguard Worker
100*2d543d20SAndroid Build Coastguard Worker    def test_include_file(self):
101*2d543d20SAndroid Build Coastguard Worker        "Verify that sandbox can copy a file in the sandbox home and use it"
102*2d543d20SAndroid Build Coastguard Worker        p = Popen([sys.executable, 'sandbox', '-i' ,'test_sandbox.py' , '-M', '/bin/cat', 'test_sandbox.py'],
103*2d543d20SAndroid Build Coastguard Worker                  stdout=PIPE, stderr=PIPE)
104*2d543d20SAndroid Build Coastguard Worker        out, err = p.communicate()
105*2d543d20SAndroid Build Coastguard Worker        self.assertSuccess(p.returncode, err)
106*2d543d20SAndroid Build Coastguard Worker
107*2d543d20SAndroid Build Coastguard Worker
108*2d543d20SAndroid Build Coastguard Workerif __name__ == "__main__":
109*2d543d20SAndroid Build Coastguard Worker    import selinux
110*2d543d20SAndroid Build Coastguard Worker    if selinux.is_selinux_enabled() and selinux.security_getenforce() == 1:
111*2d543d20SAndroid Build Coastguard Worker        unittest.main()
112*2d543d20SAndroid Build Coastguard Worker    else:
113*2d543d20SAndroid Build Coastguard Worker        print("SELinux must be in enforcing mode for this test")
114