blob: 19672a181402a800f63e810bab6b64d8bda87577 [file] [log] [blame]
Paul Lawrence7ea40902017-02-14 13:32:23 -08001#!/usr/bin/env python
2# Unit tests for genseccomp.py
3
4import cStringIO
5import textwrap
6import unittest
7
8import genseccomp
9
10class TestGenseccomp(unittest.TestCase):
11 def setUp(self):
12 genseccomp.set_dir()
13
14 def get_config(self, arch):
15 for i in genseccomp.POLICY_CONFIGS:
16 if i[0] == arch:
17 return i
18 self.fail("No such architecture")
19
20 def get_headers(self, arch):
21 return self.get_config(arch)[1]
22
Paul Lawrence89fa81f2017-02-17 10:22:03 -080023 def get_switches(self, arch):
24 return self.get_config(arch)[2]
25
Paul Lawrence7ea40902017-02-14 13:32:23 -080026 def test_get_names(self):
27 syscalls = cStringIO.StringIO(textwrap.dedent("""\
28int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
29int fchown:fchown(int, uid_t, gid_t) arm64,mips,mips64,x86_64
30 """))
31
32 whitelist = cStringIO.StringIO(textwrap.dedent("""\
33ssize_t read(int, void*, size_t) all
34 """))
35
36 syscall_files = [syscalls, whitelist]
37 names = genseccomp.get_names(syscall_files, "arm")
38 for f in syscall_files:
39 f.seek(0)
40 names64 = genseccomp.get_names(syscall_files, "arm64")
41
42 self.assertIn("fchown", names64)
43 self.assertNotIn("fchown", names)
44 self.assertIn("_llseek", names)
45 self.assertNotIn("_llseek", names64)
46 self.assertIn("read", names)
47 self.assertIn("read", names64)
48
49 def test_convert_names_to_NRs(self):
50 self.assertEquals(genseccomp.convert_names_to_NRs(["open"],
Paul Lawrence89fa81f2017-02-17 10:22:03 -080051 self.get_headers("arm"),
52 self.get_switches("arm")),
Paul Lawrence7ea40902017-02-14 13:32:23 -080053 [("open", 5)])
54
55 self.assertEquals(genseccomp.convert_names_to_NRs(["__ARM_NR_set_tls"],
Paul Lawrence89fa81f2017-02-17 10:22:03 -080056 self.get_headers("arm"),
57 self.get_switches("arm")),
Paul Lawrence7ea40902017-02-14 13:32:23 -080058 [('__ARM_NR_set_tls', 983045)])
59
60 self.assertEquals(genseccomp.convert_names_to_NRs(["openat"],
Paul Lawrence89fa81f2017-02-17 10:22:03 -080061 self.get_headers("arm64"),
62 self.get_switches("arm64")),
Paul Lawrence7ea40902017-02-14 13:32:23 -080063 [("openat", 56)])
64
Paul Lawrence89fa81f2017-02-17 10:22:03 -080065 self.assertEquals(genseccomp.convert_names_to_NRs(["openat"],
66 self.get_headers("x86"),
67 self.get_switches("x86")),
68 [("openat", 295)])
69
70 self.assertEquals(genseccomp.convert_names_to_NRs(["openat"],
71 self.get_headers("x86_64"),
72 self.get_switches("x86_64")),
73 [("openat", 257)])
74
75 self.assertEquals(genseccomp.convert_names_to_NRs(["openat"],
76 self.get_headers("mips"),
77 self.get_switches("mips")),
78 [("openat", 4288)])
79
80 self.assertEquals(genseccomp.convert_names_to_NRs(["openat"],
81 self.get_headers("mips64"),
82 self.get_switches("mips64")),
83 [("openat", 5247)])
84
Paul Lawrence7ea40902017-02-14 13:32:23 -080085
86 def test_convert_NRs_to_ranges(self):
87 ranges = genseccomp.convert_NRs_to_ranges([("b", 2), ("a", 1)])
88 self.assertEquals(len(ranges), 1)
89 self.assertEquals(ranges[0].begin, 1)
90 self.assertEquals(ranges[0].end, 3)
91 self.assertItemsEqual(ranges[0].names, ["a", "b"])
92
93 ranges = genseccomp.convert_NRs_to_ranges([("b", 3), ("a", 1)])
94 self.assertEquals(len(ranges), 2)
95 self.assertEquals(ranges[0].begin, 1)
96 self.assertEquals(ranges[0].end, 2)
97 self.assertItemsEqual(ranges[0].names, ["a"])
98 self.assertEquals(ranges[1].begin, 3)
99 self.assertEquals(ranges[1].end, 4)
100 self.assertItemsEqual(ranges[1].names, ["b"])
101
102 def test_convert_to_intermediate_bpf(self):
103 ranges = genseccomp.convert_NRs_to_ranges([("b", 2), ("a", 1)])
104 bpf = genseccomp.convert_to_intermediate_bpf(ranges)
105 self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, {fail}, {allow}), //a|b'])
106
107 ranges = genseccomp.convert_NRs_to_ranges([("b", 3), ("a", 1)])
108 bpf = genseccomp.convert_to_intermediate_bpf(ranges)
109 self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),',
110 'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, {fail}, {allow}), //a',
111 'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, {fail}, {allow}), //b'])
112
113 def test_convert_ranges_to_bpf(self):
114 ranges = genseccomp.convert_NRs_to_ranges([("b", 2), ("a", 1)])
115 bpf = genseccomp.convert_ranges_to_bpf(ranges)
116 self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 1),',
117 'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0), //a|b',
118 'BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),'])
119
120 ranges = genseccomp.convert_NRs_to_ranges([("b", 3), ("a", 1)])
121 bpf = genseccomp.convert_ranges_to_bpf(ranges)
122 self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 3),',
123 'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),',
124 'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 2, 1), //a',
125 'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 1, 0), //b',
126 'BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),'])
127
128 def test_convert_bpf_to_output(self):
129 output = genseccomp.convert_bpf_to_output(["line1", "line2"], "arm")
130 expected_output = textwrap.dedent("""\
131 // Autogenerated file - edit at your peril!!
132
133 #include <linux/filter.h>
134 #include <errno.h>
135
Paul Lawrencedfe84342017-02-16 09:24:39 -0800136 #include "seccomp_bpfs.h"
137 const sock_filter arm_filter[] = {
Paul Lawrence7ea40902017-02-14 13:32:23 -0800138 line1
139 line2
140 };
141
142 const size_t arm_filter_size = sizeof(arm_filter) / sizeof(struct sock_filter);
143 """)
144 self.assertEquals(output, expected_output)
145
146 def test_construct_bpf(self):
147 syscalls = cStringIO.StringIO(textwrap.dedent("""\
148 int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,mips,x86
149 int fchown:fchown(int, uid_t, gid_t) arm64,mips,mips64,x86_64
150 """))
151
152 whitelist = cStringIO.StringIO(textwrap.dedent("""\
153 ssize_t read(int, void*, size_t) all
154 """))
155
156 syscall_files = [syscalls, whitelist]
Paul Lawrence89fa81f2017-02-17 10:22:03 -0800157 output = genseccomp.construct_bpf(syscall_files, "arm", self.get_headers("arm"),
158 self.get_switches("arm"))
Paul Lawrence7ea40902017-02-14 13:32:23 -0800159
160 expected_output = textwrap.dedent("""\
161 // Autogenerated file - edit at your peril!!
162
163 #include <linux/filter.h>
164 #include <errno.h>
165
Paul Lawrencedfe84342017-02-16 09:24:39 -0800166 #include "seccomp_bpfs.h"
167 const sock_filter arm_filter[] = {
Paul Lawrence7ea40902017-02-14 13:32:23 -0800168 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 0, 3),
169 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 1, 0),
170 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 2, 1), //read
171 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 141, 1, 0), //_llseek
172 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
173 };
174
175 const size_t arm_filter_size = sizeof(arm_filter) / sizeof(struct sock_filter);
176 """)
177 self.assertEquals(output, expected_output)
178
179
180if __name__ == '__main__':
181 unittest.main()