Home | History | Annotate | Download | only in security_RestartJob
      1 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import dbus
      6 import logging
      7 import os.path
      8 import socket
      9 
     10 from autotest_lib.client.bin import test, utils
     11 from autotest_lib.client.common_lib import error
     12 from autotest_lib.client.cros import constants, cros_ui, login
     13 
     14 
     15 class security_RestartJob(test.test):
     16     """Verifies that RestartJob cannot be abused to execute arbitrary processes.
     17     """
     18     version = 1
     19 
     20 
     21     _FLAGFILE = '/tmp/security_RestartJob_regression'
     22 
     23 
     24     def _ps(self, proc=constants.BROWSER):
     25         """Grab the oldest pid for a process named |proc|."""
     26         pscmd = 'ps -C %s -o pid --no-header | head -1' % proc
     27         return utils.system_output(pscmd)
     28 
     29 
     30     def run_once(self):
     31         """Main test code."""
     32         login.wait_for_browser()
     33         bus = dbus.SystemBus()
     34         proxy = bus.get_object('org.chromium.SessionManager',
     35                                '/org/chromium/SessionManager')
     36         sessionmanager = dbus.Interface(proxy,
     37                                         'org.chromium.SessionManagerInterface')
     38 
     39         # Craft a malicious replacement for the target process.
     40         cmd = ['touch', self._FLAGFILE]
     41 
     42         # Try to get our malicious replacement to run via RestartJob.
     43         try:
     44             remote, local = socket.socketpair(socket.AF_UNIX)
     45             logging.info('Calling RestartJob(<socket>, %r)', cmd)
     46             sessionmanager.RestartJob(dbus.types.UnixFd(remote), cmd)
     47             # Fails if the RestartJob call doesn't generate an error.
     48             raise error.TestFail('RestartJob regression!')
     49         except dbus.DBusException as e:
     50             logging.info(e.get_dbus_message())
     51             pass
     52         except OSError as e:
     53             raise error.TestError('Could not create sockets for creds: %s', e)
     54         finally:
     55             try:
     56                 local.close()
     57             except OSError:
     58                 pass
     59 
     60         if os.path.exists(self._FLAGFILE):
     61             raise error.TestFail('RestartJobWithAuth regression!')
     62 
     63 
     64     def cleanup(self):
     65         """Reset the UI, since this test killed Chrome."""
     66         cros_ui.nuke()
     67