blob: 2c0e1b57373c1092c4710bc3e449d37bd6ea5740 [file] [log] [blame]
Jorge Lucangeli Obes3ce29f42012-06-22 15:54:54 -07001# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Radoslav Vasilev289b4962010-07-09 10:40:16 +02002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5
Thieu Lede232f52010-09-29 11:05:17 -07006import os, subprocess, time, re
Eric Lie7c4cab2011-01-05 14:39:19 -08007from autotest_lib.client.bin import utils
Eric Lic4d8f4a2010-12-10 09:49:23 -08008from autotest_lib.client.common_lib import error
Eric Lie7c4cab2011-01-05 14:39:19 -08009from autotest_lib.client.cros import cros_ui_test, login
Radoslav Vasilev289b4962010-07-09 10:40:16 +020010
Eric Lie7c4cab2011-01-05 14:39:19 -080011class security_RendererSandbox(cros_ui_test.UITest):
Radoslav Vasilev289b4962010-07-09 10:40:16 +020012 version = 1
13 render_pid = -1
14
Antoine Labour2d20c3b2010-10-29 16:03:17 -070015
16 def check_for_seccomp_sandbox(self):
17 # the seccomp sandbox has exactly one child process that has no
18 # other threads, this is the trusted helper process.
19 seccomp = subprocess.Popen(['ps', 'h', '--format', 'pid',
20 '--ppid', '%s' % self.render_pid],
21 stdout=subprocess.PIPE)
22 helper_processes = seccomp.communicate()[0].splitlines()
23 if len(helper_processes) != 1:
24 raise error.TestFail('Invalid number of Renderer child process')
25
26 helper_pid = helper_processes[0].strip()
27 threads = os.listdir('/proc/%s/task' % helper_pid)
28 if len(threads) != 1:
29 raise error.TestFail('Invalid number of helper process threads')
30
31 exe = os.readlink('/proc/%s/exe' % helper_pid)
32 pattern = re.compile('/chrome$')
33 chrome = pattern.search(exe)
34 if chrome == None:
35 raise error.TestFail('Invalid child process executable')
36
37
38 def check_for_suid_sandbox(self):
39 # for setuid sandbox, make sure there is no content in the CWD
40 # directory
41 cwd_contents = os.listdir('/proc/%s/cwd' % self.render_pid)
42 if len(cwd_contents) > 0:
43 raise error.TestFail('Contents present in the CWD directory')
44
45
Radoslav Vasilev289b4962010-07-09 10:40:16 +020046 def run_once(self, time_to_wait=20):
Radoslav Vasilev289b4962010-07-09 10:40:16 +020047
Radoslav Vasilev40fef152010-07-13 17:54:45 +020048 # wait till the page is loaded and poll for the renderer pid
49 # if renderer pid is found, it is stored in self.render_pid
Eric Licb6a91a2010-12-08 17:08:09 -080050 utils.poll_for_condition(
Radoslav Vasilev40fef152010-07-13 17:54:45 +020051 self._get_renderer_pid,
52 error.TestFail('Timed out waiting to obtain pid of renderer'),
53 time_to_wait)
Radoslav Vasilev289b4962010-07-09 10:40:16 +020054
Thieu Lede232f52010-09-29 11:05:17 -070055 # check if renderer is sandboxed
56 # for now, x86 renderer must be running in a seccomp sandbox and
57 # arm render must run in a setuid sandbox
58 arch = utils.get_arch()
59 if arch == 'i386':
Antoine Labour2d20c3b2010-10-29 16:03:17 -070060 # Seccomp is currently disabled because of performance issues. See
61 # crosbug.com/8397
62 # self.check_for_seccomp_sandbox()
63 self.check_for_suid_sandbox()
Thieu Lede232f52010-09-29 11:05:17 -070064 else:
Antoine Labour2d20c3b2010-10-29 16:03:17 -070065 self.check_for_suid_sandbox()
Radoslav Vasilev289b4962010-07-09 10:40:16 +020066
67
68 # queries pgrep for the pid of the renderer. since this function is passed
Eric Licb6a91a2010-12-08 17:08:09 -080069 # as an argument to utils.poll_for_condition, the return values are set
Radoslav Vasilev289b4962010-07-09 10:40:16 +020070 # to true/false depending on whether a pid has been found
Jorge Lucangeli Obes3ce29f42012-06-22 15:54:54 -070071 def _get_renderer_pid(self):
72 pgrep = subprocess.Popen(['pgrep', '-f', '-l', 'type=renderer'],
Radoslav Vasilev289b4962010-07-09 10:40:16 +020073 stdout=subprocess.PIPE)
Jorge Lucangeli Obes3ce29f42012-06-22 15:54:54 -070074 procs = pgrep.communicate()[0].splitlines()
75 pids = []
76 # we're adding '--ignored= --type=renderer' to the GPU process cmdline
77 # to fix http://code.google.com/p/chromium/issues/detail?id=129884
78 # this confuses 'pgrep' above, returning the pid of the GPU process,
79 # which is not sandboxed, as the pid of a renderer, breaking the test
80 for proc in procs:
81 if '--ignored= --type=renderer' not in proc:
82 pids.append(proc.split()[0])
83
Radoslav Vasilev289b4962010-07-09 10:40:16 +020084 if pids:
85 self.render_pid = pids[0]
86 return True
87 else:
Thieu Lede232f52010-09-29 11:05:17 -070088 return False