• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright 2020 The ChromiumOS Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unittests for the seccomp policy linter module."""
7
8from pathlib import Path
9import tempfile
10import unittest
11
12import seccomp_policy_lint
13
14
15class CheckSeccompPolicyTests(unittest.TestCase):
16    """Tests for check_seccomp_policy."""
17
18    def setUp(self):
19        self.tempdir = Path(tempfile.mkdtemp())
20
21    def _write_file(self, filename, contents):
22        """Helper to write out a file for testing."""
23        path = self.tempdir / filename
24        path.write_text(contents)
25        return path
26
27    def test_check_simple(self):
28        """Allow simple policy files."""
29        path = self._write_file(
30            "test.policy",
31            """
32            # Comment.\n
33            read: 1\n
34            write: 1\n
35        """,
36        )
37
38        exp_out = seccomp_policy_lint.CheckPolicyReturn(
39            f"seccomp: {path.resolve()} does not contain any dangerous"
40            " syscalls, so does not require review from"
41            " chromeos-security@",
42            [],
43        )
44
45        with path.open("r", encoding="utf-8") as check_file:
46            self.assertEqual(
47                seccomp_policy_lint.check_seccomp_policy(
48                    check_file, seccomp_policy_lint.DANGEROUS_SYSCALLS
49                ),
50                exp_out,
51            )
52
53    def test_check_dangerous_comment(self):
54        """Dangerous syscalls must have a comment and need to be reviewed."""
55        path = self._write_file(
56            "test.policy",
57            """
58            # Comment.\n\n\n
59            clone: 1\n
60            write: 1\n
61        """,
62        )
63
64        exp_out = seccomp_policy_lint.CheckPolicyReturn(
65            f"seccomp: {path.resolve()} contains dangerous syscalls,"
66            " so requires review from chromeos-security@",
67            [],
68        )
69
70        with path.open("r", encoding="utf-8") as check_file:
71            self.assertEqual(
72                seccomp_policy_lint.check_seccomp_policy(
73                    check_file, seccomp_policy_lint.DANGEROUS_SYSCALLS
74                ),
75                exp_out,
76            )
77
78    def test_check_dangerous_no_comment(self):
79        """Dangerous syscalls without a comment should cause an error."""
80        path = self._write_file(
81            "test.policy",
82            """
83            # Comment.\n
84            mount: 1\n
85            clone: 1\n
86        """,
87        )
88
89        exp_out = seccomp_policy_lint.CheckPolicyReturn(
90            f"seccomp: {path.resolve()} contains dangerous syscalls,"
91            " so requires review from chromeos-security@",
92            [
93                (
94                    f"{path.resolve()}:5:clone: syscall is dangerous "
95                    "and requires a comment on the preceding line"
96                )
97            ],
98        )
99
100        with path.open("r", encoding="utf-8") as check_file:
101            self.assertEqual(
102                seccomp_policy_lint.check_seccomp_policy(
103                    check_file, seccomp_policy_lint.DANGEROUS_SYSCALLS
104                ),
105                exp_out,
106            )
107
108    def test_check_duplicate_syscall(self):
109        """Policy files cannot have duplicate syscalls.."""
110        path = self._write_file(
111            "test.policy",
112            """
113            # Comment.\n
114            clone: 1\n
115            clone: arg0 == 3
116        """,
117        )
118
119        exp_out = seccomp_policy_lint.CheckPolicyReturn(
120            f"seccomp: {path.resolve()} contains dangerous syscalls,"
121            " so requires review from chromeos-security@",
122            [f"{path.resolve()}:5:clone: duplicate entry found"],
123        )
124
125        with path.open("r", encoding="utf-8") as check_file:
126            self.assertEqual(
127                seccomp_policy_lint.check_seccomp_policy(
128                    check_file, seccomp_policy_lint.DANGEROUS_SYSCALLS
129                ),
130                exp_out,
131            )
132
133
134if __name__ == "__main__":
135    unittest.main()
136