Merge lp:~kissiel/qa-regression-testing/kernel-sec-py3-friendly into lp:qa-regression-testing

Proposed by Maciej Kisielewski
Status: Merged
Approved by: Alberto Salvia Novella
Approved revision: 2559
Merged at revision: 2556
Proposed branch: lp:~kissiel/qa-regression-testing/kernel-sec-py3-friendly
Merge into: lp:qa-regression-testing
Diff against target: 270 lines (+42/-34)
5 files modified
scripts/kernel-security/errno-read.py (+8/-5)
scripts/kernel-security/proc-leaks/dac-bypass.py (+5/-5)
scripts/kernel-security/proc-maps/maps-protection.py (+1/-1)
scripts/test-kernel-security.py (+1/-1)
scripts/testlib.py (+27/-22)
To merge this branch: bzr merge lp:~kissiel/qa-regression-testing/kernel-sec-py3-friendly
Reviewer Review Type Date Requested Status
Alberto Salvia Novella (community) Approve
Review via email: mp+302017@code.launchpad.net

Description of the change

This MR makes all python code in kernel-security suite python3 friendly as well as testlib.py
print conversions were done using 2to3, other issues were done manually.

This helps significantly when porting the security suite to snappy.

It would be even better if I'd be allowed to make all those tests explicitly run python3 (by changing shebangs).

Comments welcome!

Changes made:
* print as a function
* explicitly decoding output from std{out,err}
* s/self.assertNotEquals/self.assertNotEqual/
* explicitly closing open files
* bytes literals instead of strings when used with conjuction with the raw output of std{out,err}
* 0o0000 notation for octal literals
* 'as' syntax for catching exceptions
* string.ascii_letters instead of locale-dependent string.letters
* /usr/bin/env python instead of absolute /usr/bin/python in shebangs

To post a comment you must log in.
Revision history for this message
Alberto Salvia Novella (es20490446e) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'scripts/kernel-security/errno-read.py'
--- scripts/kernel-security/errno-read.py 2009-04-03 00:53:35 +0000
+++ scripts/kernel-security/errno-read.py 2016-08-04 12:39:13 +0000
@@ -1,9 +1,12 @@
1#!/usr/bin/python1#!/usr/bin/env python
2from __future__ import print_function
2import sys3import sys
3try:4try:
4 file(sys.argv[1]).read(int(sys.argv[2]))5 f = open(sys.argv[1])
5except IOError, e:6 f.read(int(sys.argv[2]))
6 print >>sys.stderr, "%s: %s" % (sys.argv[1], e.strerror)7 f.close()
8except IOError as e:
9 print("%s: %s" % (sys.argv[1], e.strerror), file=sys.stderr)
7 sys.exit(e.errno)10 sys.exit(e.errno)
8print "%s: Success" % (sys.argv[1])11print("%s: Success" % (sys.argv[1]))
9sys.exit(0)12sys.exit(0)
1013
=== modified file 'scripts/kernel-security/proc-leaks/dac-bypass.py'
--- scripts/kernel-security/proc-leaks/dac-bypass.py 2012-03-21 14:49:14 +0000
+++ scripts/kernel-security/proc-leaks/dac-bypass.py 2016-08-04 12:39:13 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/env python
2# Demonstrates DAC bypass on /proc/$pid file descriptors across setuid exec2# Demonstrates DAC bypass on /proc/$pid file descriptors across setuid exec
3# Author: Kees Cook <kees@ubuntu.com>3# Author: Kees Cook <kees@ubuntu.com>
4# License: GPLv24# License: GPLv2
@@ -21,9 +21,9 @@
21 auxv = struct.unpack('@%dL' % (len(blob)/len(struct.pack('@L',0))), blob)21 auxv = struct.unpack('@%dL' % (len(blob)/len(struct.pack('@L',0))), blob)
22 while auxv[0] != 0:22 while auxv[0] != 0:
23 if auxv[0] == 7:23 if auxv[0] == 7:
24 print "AT_BASE: 0x%x" % (auxv[1])24 print("AT_BASE: 0x%x" % (auxv[1]))
25 if auxv[0] == 25:25 if auxv[0] == 25:
26 print "AT_RANDOM: 0x%x" % (auxv[1])26 print("AT_RANDOM: 0x%x" % (auxv[1]))
27 auxv = auxv[2:]27 auxv = auxv[2:]
2828
29# Allow child/parent synchronization to avoid start-up race.29# Allow child/parent synchronization to avoid start-up race.
@@ -55,9 +55,9 @@
55 if name == 'auxv':55 if name == 'auxv':
56 dump_auxv(saw)56 dump_auxv(saw)
57 else:57 else:
58 print saw58 print(saw)
59 last[name] = saw59 last[name] = saw
60 except Exception, o:60 except Exception as o:
61 if o.errno == errno.EEXIST or o.errno == errno.EPERM:61 if o.errno == errno.EEXIST or o.errno == errno.EPERM:
62 # Target quit or wasn't permitted to access the file to62 # Target quit or wasn't permitted to access the file to
63 # begin with, so okay.63 # begin with, so okay.
6464
=== modified file 'scripts/kernel-security/proc-maps/maps-protection.py'
--- scripts/kernel-security/proc-maps/maps-protection.py 2013-11-27 23:58:15 +0000
+++ scripts/kernel-security/proc-maps/maps-protection.py 2016-08-04 12:39:13 +0000
@@ -81,7 +81,7 @@
8181
82 info = os.stat('maps-helper-setuid')82 info = os.stat('maps-helper-setuid')
83 self.assertEqual(info.st_uid, 0, "maps-helper-setuid not owned by root")83 self.assertEqual(info.st_uid, 0, "maps-helper-setuid not owned by root")
84 self.assertEqual(info.st_mode & 04000, 04000, "maps-helper-setuid not setuid")84 self.assertEqual(info.st_mode & 0o4000, 0o4000, "maps-helper-setuid not setuid")
8585
86 def test_30_setuid_before_dropping_privs(self):86 def test_30_setuid_before_dropping_privs(self):
87 '''Can not read setuid process before priv-dropping to our uid'''87 '''Can not read setuid process before priv-dropping to our uid'''
8888
=== modified file 'scripts/test-kernel-security.py'
--- scripts/test-kernel-security.py 2016-06-27 16:06:54 +0000
+++ scripts/test-kernel-security.py 2016-08-04 12:39:13 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/env python
2#2#
3# kernel-security.py regression testing script for kernel and3# kernel-security.py regression testing script for kernel and
4# security features4# security features
55
=== modified file 'scripts/testlib.py'
--- scripts/testlib.py 2016-06-26 15:39:53 +0000
+++ scripts/testlib.py 2016-08-04 12:39:13 +0000
@@ -19,6 +19,7 @@
1919
20'''Common classes and functions for package tests.'''20'''Common classes and functions for package tests.'''
2121
22from __future__ import print_function
22import string, random, crypt, subprocess, pwd, grp, time, unittest, tempfile, shutil, os, os.path, re, glob23import string, random, crypt, subprocess, pwd, grp, time, unittest, tempfile, shutil, os, os.path, re, glob
23import sys, socket, gzip24import sys, socket, gzip
2425
@@ -179,20 +180,20 @@
179180
180def require_nonroot():181def require_nonroot():
181 if os.geteuid() == 0:182 if os.geteuid() == 0:
182 print >>sys.stderr, "This series of tests should be run as a regular user with sudo access, not as root."183 print("This series of tests should be run as a regular user with sudo access, not as root.", file=sys.stderr)
183 sys.exit(1)184 sys.exit(1)
184185
185def require_root():186def require_root():
186 if os.geteuid() != 0:187 if os.geteuid() != 0:
187 print >>sys.stderr, "This series of tests should be run with root privileges (e.g. via sudo)."188 print("This series of tests should be run with root privileges (e.g. via sudo).", file=sys.stderr)
188 sys.exit(1)189 sys.exit(1)
189190
190def require_sudo():191def require_sudo():
191 if os.geteuid() != 0 or os.environ.get('SUDO_USER', None) is None:192 if os.geteuid() != 0 or os.environ.get('SUDO_USER', None) is None:
192 print >>sys.stderr, "This series of tests must be run under sudo."193 print("This series of tests must be run under sudo.", file=sys.stderr)
193 sys.exit(1)194 sys.exit(1)
194 if os.environ['SUDO_USER'] == 'root':195 if os.environ['SUDO_USER'] == 'root':
195 print >>sys.stderr, 'Please run this test using sudo from a regular user. (You ran sudo from root.)'196 print('Please run this test using sudo from a regular user. (You ran sudo from root.)', file=sys.stderr)
196 sys.exit(1)197 sys.exit(1)
197198
198def random_string(length,lower=False):199def random_string(length,lower=False):
@@ -200,7 +201,7 @@
200 length.'''201 length.'''
201202
202 s = ''203 s = ''
203 selection = string.letters204 selection = string.ascii_letters
204 if lower:205 if lower:
205 selection = string.lowercase206 selection = string.lowercase
206 maxind = len(selection)-1207 maxind = len(selection)-1
@@ -402,11 +403,11 @@
402 out, outerr = sp.communicate(input)403 out, outerr = sp.communicate(input)
403 # Handle redirection of stdout404 # Handle redirection of stdout
404 if out is None:405 if out is None:
405 out = ''406 out = b''
406 # Handle redirection of stderr407 # Handle redirection of stderr
407 if outerr is None:408 if outerr is None:
408 outerr = ''409 outerr = b''
409 return [sp.returncode, out + outerr]410 return [sp.returncode, out.decode(sys.stdout.encoding) + outerr.decode(sys.stderr.encoding)]
410411
411def cmd_pipe(command1, command2, input = None, stderr = subprocess.STDOUT, stdin = None):412def cmd_pipe(command1, command2, input = None, stderr = subprocess.STDOUT, stdin = None):
412 '''Try to pipe command1 into command2.'''413 '''Try to pipe command1 into command2.'''
@@ -594,7 +595,7 @@
594 rc, report = cmd(['apt-get','source',source])595 rc, report = cmd(['apt-get','source',source])
595 assert (rc == 0)596 assert (rc == 0)
596 shutil.copytree(build_src, cached_src)597 shutil.copytree(build_src, cached_src)
597 print "(unpacked %s)" % os.path.basename(glob.glob('%s_*.dsc' % source)[0]),598 print("(unpacked %s)" % os.path.basename(glob.glob('%s_*.dsc' % source)[0]), end=' ')
598599
599600
600 unpacked_dir = os.path.join(build_src, glob.glob('%s-*' % source)[0])601 unpacked_dir = os.path.join(build_src, glob.glob('%s-*' % source)[0])
@@ -720,7 +721,7 @@
720 # check for it.721 # check for it.
721 rc, report = cmd(['ps', 'x'])722 rc, report = cmd(['ps', 'x'])
722 if 'kdeinit4 Running' not in report:723 if 'kdeinit4 Running' not in report:
723 print >>sys.stderr, ("kdeinit not running (you may start/stop any KDE application then run this script again)")724 print(("kdeinit not running (you may start/stop any KDE application then run this script again)"), file=sys.stderr)
724 return False725 return False
725 return True726 return True
726727
@@ -730,7 +731,7 @@
730 rc, pkg_config = cmd(['pkg-config', '--cflags', '--libs'] + libs)731 rc, pkg_config = cmd(['pkg-config', '--cflags', '--libs'] + libs)
731 expected = 0732 expected = 0
732 if rc != expected:733 if rc != expected:
733 print >>sys.stderr, 'Got exit code %d, expected %d\n' % (rc, expected)734 print('Got exit code %d, expected %d\n' % (rc, expected), file=sys.stderr)
734 assert(rc == expected)735 assert(rc == expected)
735 return pkg_config.split()736 return pkg_config.split()
736737
@@ -739,7 +740,7 @@
739 rc, output = cmd(['capsh', '--decode=%x' % cap_num])740 rc, output = cmd(['capsh', '--decode=%x' % cap_num])
740 expected = 0741 expected = 0
741 if rc != expected:742 if rc != expected:
742 print >>sys.stderr, 'capsh: got exit code %d, expected %d\n' % (rc, expected)743 print('capsh: got exit code %d, expected %d\n' % (rc, expected), file=sys.stderr)
743 cap_name = output.strip().split('=')[1]744 cap_name = output.strip().split('=')[1]
744 return cap_name745 return cap_name
745746
@@ -856,7 +857,7 @@
856 if not os.path.exists('/usr/bin/lsb_release') and not os.path.exists('/bin/lsb_release'):857 if not os.path.exists('/usr/bin/lsb_release') and not os.path.exists('/bin/lsb_release'):
857 raise OSError("Please install 'lsb-release'")858 raise OSError("Please install 'lsb-release'")
858 for line in subprocess.Popen(['lsb_release','-a'],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()[0].splitlines():859 for line in subprocess.Popen(['lsb_release','-a'],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()[0].splitlines():
859 field, value = line.split(':',1)860 field, value = line.decode(sys.stdout.encoding).split(':',1)
860 value=value.strip()861 value=value.strip()
861 field=field.strip()862 field=field.strip()
862 # Convert numerics863 # Convert numerics
@@ -933,14 +934,14 @@
933 kernel = self.kernel_version_ubuntu934 kernel = self.kernel_version_ubuntu
934 if kernel != self.kernel_version_signature:935 if kernel != self.kernel_version_signature:
935 kernel += " (%s)" % (self.kernel_version_signature)936 kernel += " (%s)" % (self.kernel_version_signature)
936 print >>sys.stdout, "Running test: '%s' distro: '%s %.2f' kernel: '%s' arch: '%s' uid: %d/%d SUDO_USER: '%s')" % ( \937 print("Running test: '%s' distro: '%s %.2f' kernel: '%s' arch: '%s' uid: %d/%d SUDO_USER: '%s')" % ( \
937 sys.argv[0],938 sys.argv[0],
938 self.lsb_release['Distributor ID'],939 self.lsb_release['Distributor ID'],
939 self.lsb_release['Release'],940 self.lsb_release['Release'],
940 kernel,941 kernel,
941 self.dpkg_arch,942 self.dpkg_arch,
942 os.geteuid(), os.getuid(),943 os.geteuid(), os.getuid(),
943 os.environ.get('SUDO_USER', ''))944 os.environ.get('SUDO_USER', '')), file=sys.stdout)
944 sys.stdout.flush()945 sys.stdout.flush()
945946
946 # Additional heuristics947 # Additional heuristics
@@ -952,7 +953,7 @@
952 # time.sleep(0.5)953 # time.sleep(0.5)
953954
954 def hello(self, msg):955 def hello(self, msg):
955 print >>sys.stderr, "Hello from %s" % (msg)956 print("Hello from %s" % (msg), file=sys.stderr)
956# The central instance957# The central instance
957manager = TestlibManager()958manager = TestlibManager()
958959
@@ -1000,7 +1001,7 @@
1000 # accept if the beginning of the line matches1001 # accept if the beginning of the line matches
1001 filetype = '^%s' % (filetype)1002 filetype = '^%s' % (filetype)
1002 result = 'File type reported by file: [%s], expected regex: [%s]\n' % (out, filetype)1003 result = 'File type reported by file: [%s], expected regex: [%s]\n' % (out, filetype)
1003 self.assertNotEquals(None, re.search(filetype, out), result)1004 self.assertNotEqual(None, re.search(filetype, out), result)
10041005
1005 def yank_commonname_from_cert(self, certfile):1006 def yank_commonname_from_cert(self, certfile):
1006 '''Extract the commonName from a given PEM'''1007 '''Extract the commonName from a given PEM'''
@@ -1016,7 +1017,7 @@
10161017
1017 def announce(self, text):1018 def announce(self, text):
1018 if self.my_verbosity:1019 if self.my_verbosity:
1019 print >>sys.stdout, "(%s) " % (text),1020 print("(%s) " % (text), end=' ', file=sys.stdout)
1020 sys.stdout.flush()1021 sys.stdout.flush()
10211022
1022 def make_clean(self):1023 def make_clean(self):
@@ -1078,7 +1079,7 @@
1078 '''Test a shell command doesn't match a specific exit code'''1079 '''Test a shell command doesn't match a specific exit code'''
1079 rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)1080 rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
1080 result = 'Got (unwanted) exit code %d\n' % rc1081 result = 'Got (unwanted) exit code %d\n' % rc
1081 self.assertNotEquals(unwanted, rc, msg + result + report)1082 self.assertNotEqual(unwanted, rc, msg + result + report)
10821083
1083 def assertShellOutputContains(self, text, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg="", invert=False, expected=None):1084 def assertShellOutputContains(self, text, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg="", invert=False, expected=None):
1084 '''Test a shell command contains a specific output'''1085 '''Test a shell command contains a specific output'''
@@ -1099,7 +1100,7 @@
1099 if not invert:1100 if not invert:
1100 self.assertEqual(text, out, msg + result + report)1101 self.assertEqual(text, out, msg + result + report)
1101 else:1102 else:
1102 self.assertNotEquals(text, out, msg + result + report)1103 self.assertNotEqual(text, out, msg + result + report)
1103 if expected is not None:1104 if expected is not None:
1104 result = 'Got exit code %d. Expected %d (%s)\n' % (rc, expected, " ".join(args))1105 result = 'Got exit code %d. Expected %d (%s)\n' % (rc, expected, " ".join(args))
1105 self.assertEqual(rc, expected, msg + result + report)1106 self.assertEqual(rc, expected, msg + result + report)
@@ -1118,17 +1119,21 @@
1118 self.assertEqual(exists, os.path.exists(sysctl), sysctl)1119 self.assertEqual(exists, os.path.exists(sysctl), sysctl)
1119 value = None1120 value = None
1120 if exists:1121 if exists:
1121 value = int(open(sysctl).read())1122 f = open(sysctl)
1123 value = int(f.read())
1122 report = "%s is not %d: %d" % (sysctl, expected, value)1124 report = "%s is not %d: %d" % (sysctl, expected, value)
1123 if msg:1125 if msg:
1124 report += " (%s)" % (msg)1126 report += " (%s)" % (msg)
1125 self.assertEqual(value, expected, report)1127 self.assertEqual(value, expected, report)
1128 f.close()
1126 return value1129 return value
11271130
1128 def set_sysctl_value(self, path, desired):1131 def set_sysctl_value(self, path, desired):
1129 sysctl = '/proc/sys/%s' % (path)1132 sysctl = '/proc/sys/%s' % (path)
1130 self.assertTrue(os.path.exists(sysctl),"%s does not exist" % (sysctl))1133 self.assertTrue(os.path.exists(sysctl),"%s does not exist" % (sysctl))
1131 open(sysctl, 'w').write(str(desired))1134 f = open(sysctl, 'w')
1135 f.write(str(desired))
1136 f.close()
1132 self._test_sysctl_value(path, desired)1137 self._test_sysctl_value(path, desired)
11331138
1134 def kernel_at_least(self, introduced):1139 def kernel_at_least(self, introduced):