From 09f70981b7c857b07a786a6c3ce8041f3a8aec6b Mon Sep 17 00:00:00 2001 From: Arthur Zamarin Date: Sat, 13 Jan 2024 11:46:54 +0200 Subject: [PATCH] SandboxCallCheck: new check for invalid sandbox calls Catches multiple arguments passed to function, and colon separated path. Resolves: https://github.com/pkgcore/pkgcheck/issues/644 Signed-off-by: Arthur Zamarin --- src/pkgcheck/checks/codingstyle.py | 33 +++++++++++++++++++ .../InvalidSandboxCall/expected.json | 2 ++ .../InvalidSandboxCall/fix.patch | 17 ++++++++++ .../InvalidSandboxCall-0.ebuild | 12 +++++++ 4 files changed, 64 insertions(+) create mode 100644 testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/expected.json create mode 100644 testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/fix.patch create mode 100644 testdata/repos/standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild diff --git a/src/pkgcheck/checks/codingstyle.py b/src/pkgcheck/checks/codingstyle.py index 90cb03b2c..67dbe6c1b 100644 --- a/src/pkgcheck/checks/codingstyle.py +++ b/src/pkgcheck/checks/codingstyle.py @@ -1539,3 +1539,36 @@ def feed(self, pkg: bash.ParseTree): if len(nodes) > 1: lines = sorted(node.start_point[0] + 1 for node in nodes) yield DuplicateFunctionDefinition(func_name, lines=lines, pkg=pkg) + + +class InvalidSandboxCall(results.LineResult, results.Error): + """Invalid call to a sandbox function. + + According to PMS and the Devmanual [#]_, only a single item is allowed as + argument for ``addread``, ``addwrite``, ``adddeny``, and ``addpredict``. + Multiple path items should not be passed as a colon-separated list. + + .. [#] https://devmanual.gentoo.org/function-reference/sandbox-functions/ + """ + + @property + def desc(self): + return f"line {self.lineno}: invalid call to sandbox function: {self.line}" + + +class SandboxCallCheck(Check): + """Scan ebuilds for correct sandbox funcitons usage.""" + + _source = sources.EbuildParseRepoSource + known_results = frozenset({InvalidSandboxCall}) + + functions = frozenset({"addread", "addwrite", "adddeny", "addpredict"}) + + def feed(self, pkg: bash.ParseTree): + for node, _ in bash.cmd_query.captures(pkg.tree.root_node): + name = pkg.node_str(node.child_by_field_name("name")) + if name in self.functions: + args = node.children_by_field_name("argument") + if len(args) != 1 or ":" in pkg.node_str(args[0]): + lineno, _ = node.start_point + yield InvalidSandboxCall(line=pkg.node_str(node), lineno=lineno + 1, pkg=pkg) diff --git a/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/expected.json b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/expected.json new file mode 100644 index 000000000..bb9a68940 --- /dev/null +++ b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/expected.json @@ -0,0 +1,2 @@ +{"__class__": "InvalidSandboxCall", "category": "SandboxCallCheck", "package": "InvalidSandboxCall", "version": "0", "line": "addpredict /etc/dfs:/dev/zfs", "lineno": 7} +{"__class__": "InvalidSandboxCall", "category": "SandboxCallCheck", "package": "InvalidSandboxCall", "version": "0", "line": "addwrite /dev /etc", "lineno": 11} diff --git a/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/fix.patch b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/fix.patch new file mode 100644 index 000000000..7f28be1a5 --- /dev/null +++ b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/fix.patch @@ -0,0 +1,17 @@ +diff -Naur standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild fixed/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild +--- standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild ++++ fixed/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild +@@ -4,9 +4,11 @@ SLOT="0" + LICENSE="BSD" + + src_compile() { +- addpredict /etc/dfs:/dev/zfs ++ addpredict /etc/dfs ++ addpredict /dev/zfs + } + + src_test() { +- addwrite /dev /etc ++ addwrite /dev ++ addwrite /etc + } diff --git a/testdata/repos/standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild b/testdata/repos/standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild new file mode 100644 index 000000000..97062656a --- /dev/null +++ b/testdata/repos/standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild @@ -0,0 +1,12 @@ +DESCRIPTION="Ebuild with invalid sandbox calls" +HOMEPAGE="https://github.com/pkgcore/pkgcheck" +SLOT="0" +LICENSE="BSD" + +src_compile() { + addpredict /etc/dfs:/dev/zfs +} + +src_test() { + addwrite /dev /etc +}