Home | History | Annotate | Download | only in security_ptraceRestrictions
      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 
     18 import logging, os
     19 from autotest_lib.client.bin import test, utils
     20 from autotest_lib.client.common_lib import error
     21 
     22 class 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