1# Copyright (c) 2012 The Chromium OS Authors. 2# 3# Based on tests from http://bazaar.launchpad.net/~ubuntu-bugcontrol/qa-regression-testing/master/view/head:/scripts/test-kernel-security.py 4# Copyright (C) 2010-2011 Canonical Ltd. 5# 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License version 3, 8# as published by the Free Software Foundation. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18import logging, os 19from autotest_lib.client.bin import test, utils 20from autotest_lib.client.common_lib import error 21 22class security_ptraceRestrictions(test.test): 23 version = 1 24 25 def _passed(self, msg): 26 logging.info('ok: %s' % (msg)) 27 28 def _failed(self, msg): 29 logging.error('FAIL: %s' % (msg)) 30 self._failures.append(msg) 31 32 def _fatal(self, msg): 33 logging.error('FATAL: %s' % (msg)) 34 raise error.TestError(msg) 35 36 def check(self, boolean, msg, fatal=False): 37 if boolean == True: 38 self._passed(msg) 39 else: 40 msg = "could not satisfy '%s'" % (msg) 41 if fatal: 42 self._fatal(msg) 43 else: 44 self._failed(msg) 45 46 def setup(self): 47 # Build helpers. 48 os.chdir(self.srcdir) 49 utils.make("clean") 50 utils.make("all") 51 52 def run_once(self): 53 # Empty failure list means test passes. 54 self._failures = [] 55 56 # Verify Yama exists and has ptrace restrictions enabled. 57 sysctl = "/proc/sys/kernel/yama/ptrace_scope" 58 self.check(os.path.exists(sysctl), "%s exists" % (sysctl), fatal=True) 59 self.check(open(sysctl).read() == '1\n', "%s enabled" % (sysctl), 60 fatal=True) 61 62 os.chdir(self.srcdir) 63 64 # Verify ptrace is only allowed on children or declared processes. 65 utils.system("su -c 'bash -x ./ptrace-restrictions.sh' chronos", 66 timeout=30) 67 # Verify ptrace can be made to work across pid namespaces. 68 utils.system("bash -x ./root-ptrace-restrictions.sh chronos", 69 timeout=10) 70 # Verify ptrace of child ok from parent process and thread. 71 utils.system("su -c './thread-prctl 0 1' chronos") 72 utils.system("su -c './thread-prctl 0 0' chronos") 73 # Verify prctl(PR_SET_PTRACER, ...) ok from main process and thread. 74 utils.system("su -c './thread-prctl 1 1' chronos") 75 utils.system("su -c './thread-prctl 2 1' chronos") 76 # Verify ptrace from thread on process that used PR_SET_PTRACER. 77 utils.system("su -c './thread-prctl 1 0' chronos") 78 utils.system("su -c './thread-prctl 2 0' chronos") 79 80 # Raise a failure if anything unexpected was seen. 81 if len(self._failures): 82 raise error.TestFail((", ".join(self._failures))) 83