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