summaryrefslogtreecommitdiff
path: root/scripts/check-file-access.py
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2019-08-30 13:22:54 +0100
committerDaniel P. Berrangé <berrange@redhat.com>2019-12-20 14:23:39 +0000
commit06e6efe294f1db00b452214ee8e5975d8ae6ec42 (patch)
tree147b280ff9554c2d832c18fefb433d3c0746a74f /scripts/check-file-access.py
parent6ca74054b95876a71bb23b46d666d91b97c56ad2 (diff)
downloadlibvirt-06e6efe294f1db00b452214ee8e5975d8ae6ec42.tar.gz
tests: rewrite file access checker in Python
As part of a goal to eliminate Perl from libvirt build tools, rewrite the check-file-access.pl tool in Python. This was a straight conversion, manually going line-by-line to change the syntax from Perl to Python. Thus the overall structure of the file and approach is the same. Reviewed-by: Cole Robinson <crobinso@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Diffstat (limited to 'scripts/check-file-access.py')
-rwxr-xr-xscripts/check-file-access.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/scripts/check-file-access.py b/scripts/check-file-access.py
new file mode 100755
index 0000000000..dd39de2d79
--- /dev/null
+++ b/scripts/check-file-access.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2016-2019 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# This script is supposed to check test_file_access.txt file and
+# warn about file accesses outside our working tree.
+#
+#
+
+import re
+import sys
+
+if len(sys.argv) != 3:
+ print("syntax: %s ACCESS-FILE ACCESS-WHITELIST")
+ sys.exit(1)
+
+access_file = sys.argv[1]
+whitelist_file = sys.argv[2]
+
+known_actions = ["open", "fopen", "access", "stat", "lstat", "connect"]
+
+files = []
+whitelist = []
+
+with open(access_file, "r") as fh:
+ for line in fh:
+ line = line.rstrip("\n")
+
+ m = re.search(r'''^(\S*):\s*(\S*):\s*(\S*)(\s*:\s*(.*))?$''', line)
+ if m is not None:
+ rec = {
+ "path": m.group(1),
+ "action": m.group(2),
+ "progname": m.group(3),
+ "testname": m.group(5),
+ }
+ files.append(rec)
+ else:
+ raise Exception("Malformed line %s" % line)
+
+with open(whitelist_file, "r") as fh:
+ for line in fh:
+ line = line.rstrip("\n")
+
+ if re.search(r'''^\s*#.*$''', line):
+ continue # comment
+ if line == "":
+ continue
+
+ m = re.search(r'''^(\S*):\s*(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$''', line)
+ if m is not None and m.group(2) in known_actions:
+ # $path: $action: $progname: $testname
+ rec = {
+ "path": m.group(1),
+ "action": m.group(3),
+ "progname": m.group(4),
+ "testname": m.group(6),
+ }
+ whitelist.append(rec)
+ else:
+ m = re.search(r'''^(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$''', line)
+ if m is not None:
+ # $path: $progname: $testname
+ rec = {
+ "path": m.group(1),
+ "action": None,
+ "progname": m.group(3),
+ "testname": m.group(5),
+ }
+ whitelist.append(rec)
+ else:
+ raise Exception("Malformed line %s" % line)
+
+
+# Now we should check if %traces is included in $whitelist. For
+# now checking just keys is sufficient
+err = False
+for file in files:
+ match = False
+
+ for rule in whitelist:
+ if not re.match("^" + rule["path"] + "$", file["path"]):
+ continue
+
+ if (rule["action"] is not None and
+ not re.match("^" + rule["action"] + "$", file["action"])):
+ continue
+
+ if (rule["progname"] is not None and
+ not re.match("^" + rule["progname"] + "$", file["progname"])):
+ continue
+
+ if (rule["testname"] is not None and
+ file["testname"] is not None and
+ not re.match("^" + rule["testname"] + "$", file["testname"])):
+ continue
+
+ match = True
+
+ if not match:
+ err = True
+ print("%s: %s: %s" %
+ (file["path"], file["action"], file["progname"]),
+ end="")
+ if file["testname"] is not None:
+ print(": %s" % file["testname"], end="")
+ print("")
+
+if err:
+ sys.exit(1)
+sys.exit(0)