Ejemplo n.º 1
0
    def test_parse_simple_grouped(self):
        """Allow simple policy files."""
        path = self._write_file(
            'test.policy', """
            # Comment.
            {read, write}: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(default_action=bpf.KillProcess(),
                                filter_statements=[
                                    parser.FilterStatement(
                                        syscall=parser.Syscall('read', 0),
                                        frequency=1,
                                        filters=[
                                            parser.Filter(None, bpf.Allow()),
                                        ]),
                                    parser.FilterStatement(
                                        syscall=parser.Syscall('write', 1),
                                        frequency=1,
                                        filters=[
                                            parser.Filter(None, bpf.Allow()),
                                        ]),
                                ]))
Ejemplo n.º 2
0
    def test_parse_simple_with_arg(self):
        """Allow simple denylist policy files."""
        path = self._write_file(
            'test.policy', """
            # Comment.
            @denylist
            read: return ENOSYS
            write: arg0 == 0 ; return ENOSYS
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.Allow(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=1,
                        filters=[
                            parser.Filter(
                                None,
                                bpf.ReturnErrno(
                                    self.arch.constants['ENOSYS'])),
                        ]),
                    parser.FilterStatement(
                        syscall=parser.Syscall('write', 1),
                        frequency=1,
                        filters=[
                            parser.Filter([[parser.Atom(0, '==', 0)]],
                                          bpf.ReturnErrno(
                                              self.arch.constants['ENOSYS'])),
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))
 def test_parse_filter_statement(self):
     """Accept valid filter statements."""
     self.assertEqual(
         self.parser.parse_filter_statement(
             self._tokenize('read: arg0 == 0')),
         parser.ParsedFilterStatement((parser.Syscall('read', 0), ), [
             parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
         ]))
     self.assertEqual(
         self.parser.parse_filter_statement(
             self._tokenize('{read, write}: arg0 == 0')),
         parser.ParsedFilterStatement((
             parser.Syscall('read', 0),
             parser.Syscall('write', 1),
         ), [
             parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
         ]))
     self.assertEqual(
         self.parser.parse_filter_statement(
             self._tokenize('io@libc: arg0 == 0')),
         parser.ParsedFilterStatement((
             parser.Syscall('read', 0),
             parser.Syscall('write', 1),
         ), [
             parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
         ]))
     self.assertEqual(
         self.parser.parse_filter_statement(
             self._tokenize('file-io@systemd: arg0 == 0')),
         parser.ParsedFilterStatement((
             parser.Syscall('read', 0),
             parser.Syscall('write', 1),
         ), [
             parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
         ]))
Ejemplo n.º 4
0
 def test_parse_metadata(self):
     """Accept valid filter statements with metadata."""
     self.assertEqualIgnoringToken(
         self.parser.parse_filter_statement(
             self._tokenize('read[arch=test]: arg0 == 0')),
         parser.ParsedFilterStatement(
             syscalls=(
                 parser.Syscall('read', 0),
             ),
             filters=[
                 parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
             ],
             token=None))
     self.assertEqualIgnoringToken(
         self.parser.parse_filter_statement(
             self._tokenize(
                 '{read, nonexistent[arch=nonexistent]}: arg0 == 0')),
         parser.ParsedFilterStatement(
             syscalls=(
                 parser.Syscall('read', 0),
             ),
             filters=[
                 parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
             ],
             token=None))
Ejemplo n.º 5
0
 def test_parse_filter_statement(self):
     """Accept valid filter statements."""
     self.assertEqualIgnoringToken(
         self.parser.parse_filter_statement(
             self._tokenize('read: arg0 == 0')),
         parser.ParsedFilterStatement(
             syscalls=(parser.Syscall('read', 0), ),
             filters=[
                 parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
             ],
             token=None))
     self.assertEqualIgnoringToken(
         self.parser.parse_filter_statement(
             self._tokenize('{read, write}: arg0 == 0')),
         parser.ParsedFilterStatement(syscalls=(
             parser.Syscall('read', 0),
             parser.Syscall('write', 1),
         ),
                                      filters=[
                                          parser.Filter(
                                              [[parser.Atom(0, '==', 0)]],
                                              bpf.Allow()),
                                      ],
                                      token=None))
     self.assertEqualIgnoringToken(
         self.parser.parse_filter_statement(
             self._tokenize('io@libc: arg0 == 0')),
         parser.ParsedFilterStatement(syscalls=(
             parser.Syscall('read', 0),
             parser.Syscall('write', 1),
         ),
                                      filters=[
                                          parser.Filter(
                                              [[parser.Atom(0, '==', 0)]],
                                              bpf.Allow()),
                                      ],
                                      token=None))
     self.assertEqualIgnoringToken(
         self.parser.parse_filter_statement(
             self._tokenize('file-io@systemd: arg0 == 0')),
         parser.ParsedFilterStatement(syscalls=(
             parser.Syscall('read', 0),
             parser.Syscall('write', 1),
         ),
                                      filters=[
                                          parser.Filter(
                                              [[parser.Atom(0, '==', 0)]],
                                              bpf.Allow()),
                                      ],
                                      token=None))
     self.assertEqualIgnoringToken(
         self.parser.parse_filter_statement(
             self._tokenize('kill: arg0 == 0')),
         parser.ParsedFilterStatement(
             syscalls=(parser.Syscall('kill', 62), ),
             filters=[
                 parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
             ],
             token=None))
    def test_parse_frequency(self):
        """Allow including frequency files."""
        self._write_file(
            'test.frequency', """
            read: 2
            write: 3
        """)
        path = self._write_file(
            'test.policy', """
            @frequency ./test.frequency
            read: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=2,
                        filters=[
                            parser.Filter(None, bpf.Allow()),
                        ]),
                ]))
Ejemplo n.º 7
0
 def test_parse_filter(self):
     """Accept only filters that return an errno."""
     self.assertEqual(
         self.parser.parse_filter(
             self._tokenize('arg0 == 0; return ENOSYS')),
         [
             parser.Filter([[parser.Atom(0, '==', 0)]],
                           bpf.ReturnErrno(self.arch.constants['ENOSYS'])),
         ])
Ejemplo n.º 8
0
    def test_parse_include(self):
        """Allow including policy files."""
        path = self._write_file(
            'test.include.policy', """
            {read, write}: arg0 == 0; allow
        """)
        path = self._write_file(
            'test.policy', """
            @include ./test.include.policy
            read: return ENOSYS
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(
                default_action=bpf.KillProcess(),
                filter_statements=[
                    parser.FilterStatement(
                        syscall=parser.Syscall('read', 0),
                        frequency=1,
                        filters=[
                            parser.Filter([[parser.Atom(0, '==', 0)]],
                                          bpf.Allow()),
                            parser.Filter(
                                None,
                                bpf.ReturnErrno(
                                    self.arch.constants['ENOSYS'])),
                        ]),
                    parser.FilterStatement(
                        syscall=parser.Syscall('write', 1),
                        frequency=1,
                        filters=[
                            parser.Filter([[parser.Atom(0, '==', 0)]],
                                          bpf.Allow()),
                            parser.Filter(None, bpf.KillProcess()),
                        ]),
                ]))
Ejemplo n.º 9
0
    def test_parse_default(self):
        """Allow defining a default action."""
        path = self._write_file(
            'test.policy', """
            @default kill-thread
            read: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(default_action=bpf.KillThread(),
                                filter_statements=[
                                    parser.FilterStatement(
                                        syscall=parser.Syscall('read', 0),
                                        frequency=1,
                                        filters=[
                                            parser.Filter(None, bpf.Allow()),
                                        ]),
                                ]))
Ejemplo n.º 10
0
    def test_parse_other_arch(self):
        """Allow entries that only target another architecture."""
        path = self._write_file(
            'test.policy', """
            # Comment.
            read[arch=nonexistent]: allow
            write: allow
        """)

        self.assertEqual(
            self.parser.parse_file(path),
            parser.ParsedPolicy(default_action=bpf.KillProcess(),
                                filter_statements=[
                                    parser.FilterStatement(
                                        syscall=parser.Syscall('write', 1),
                                        frequency=1,
                                        filters=[
                                            parser.Filter(None, bpf.Allow()),
                                        ]),
                                ]))
Ejemplo n.º 11
0
 def test_parse_filter(self):
     """Accept valid filters."""
     self.assertEqual(self.parser.parse_filter(
         self._tokenize('arg0 == 0')), [
             parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
         ])
     self.assertEqual(
         self.parser.parse_filter(self._tokenize('kill-process')), [
             parser.Filter(None, bpf.KillProcess()),
         ])
     self.assertEqual(
         self.parser.parse_filter(self._tokenize('kill-thread')), [
             parser.Filter(None, bpf.KillThread()),
         ])
     self.assertEqual(self.parser.parse_filter(self._tokenize('trap')), [
         parser.Filter(None, bpf.Trap()),
     ])
     self.assertEqual(
         self.parser.parse_filter(self._tokenize('return ENOSYS')), [
             parser.Filter(None,
                           bpf.ReturnErrno(self.arch.constants['ENOSYS'])),
         ])
     self.assertEqual(self.parser.parse_filter(self._tokenize('trace')), [
         parser.Filter(None, bpf.Trace()),
     ])
     self.assertEqual(
         self.parser.parse_filter(self._tokenize('user-notify')), [
             parser.Filter(None, bpf.UserNotify()),
         ])
     self.assertEqual(self.parser.parse_filter(self._tokenize('log')), [
         parser.Filter(None, bpf.Log()),
     ])
     self.assertEqual(self.parser.parse_filter(self._tokenize('allow')), [
         parser.Filter(None, bpf.Allow()),
     ])
     self.assertEqual(self.parser.parse_filter(self._tokenize('1')), [
         parser.Filter(None, bpf.Allow()),
     ])
     self.assertEqual(
         self.parser.parse_filter(
             self._tokenize(
                 '{ arg0 == 0, arg0 == 1; return ENOSYS, trap }')),
         [
             parser.Filter([[parser.Atom(0, '==', 0)]], bpf.Allow()),
             parser.Filter([[parser.Atom(0, '==', 1)]],
                           bpf.ReturnErrno(self.arch.constants['ENOSYS'])),
             parser.Filter(None, bpf.Trap()),
         ])