• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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