1# Copyright 2017 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 5import errno 6import fcntl 7import logging 8import struct 9from autotest_lib.client.bin import test, utils 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.cros import device_jail_test_base 12from autotest_lib.client.cros import device_jail_utils 13 14 15# Definitions here are found in the uapi header linux/usbdevice_fs.h. 16 17# struct usbdevfs_ioctl { 18# int ifno; 19# int ioctl_code; 20# void __user *data; 21# }; 22def usbdevfs_ioctl(ifno, ioctl_code): 23 return struct.pack('iiP', ifno, ioctl_code, 0) 24# #define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl) 25USBDEVFS_IOCTL = (3 << 30) + \ 26 (ord('U') << 8) + \ 27 18 + \ 28 (struct.calcsize('iiP') << 16) 29# #define USBDEVFS_DISCONNECT _IO('U', 22) 30USBDEVFS_DISCONNECT = (ord('U') << 8) + 22 31 32 33class security_DeviceJail_Lockdown(device_jail_test_base.DeviceJailTestBase): 34 """ 35 Simulate permission_broker locking the device down before letting us 36 open it, and then try to perform a privileged operation such as 37 disconnecting the kernel driver. If we are allowed to perform the 38 operation, something is broken. 39 """ 40 version = 1 41 42 def _find_device_with_interface(self): 43 usb_devices = device_jail_utils.get_usb_devices() 44 if not usb_devices: 45 error.TestNAError('No USB devices found') 46 47 for device in usb_devices: 48 if not device.children: 49 continue 50 for child in device.children: 51 if child.device_type != 'usb_interface': 52 continue 53 return (device.device_node, 54 child.attributes.asint('bInterfaceNumber')) 55 56 return (None, None) 57 58 59 def run_once(self): 60 dev_path, dev_intf = self._find_device_with_interface() 61 if not dev_path: 62 raise error.TestNAError('No suitable USB devices found') 63 logging.info('Using device %s, interface %d', dev_path, dev_intf) 64 65 with device_jail_utils.JailDevice(dev_path) as jail: 66 f = jail.expect_open(device_jail_utils.REQUEST_ALLOW_WITH_LOCKDOWN) 67 if not f: 68 raise error.TestError('Failed to open allowed jail') 69 70 with f as fd: 71 try: 72 fcntl.ioctl(fd, USBDEVFS_IOCTL, 73 usbdevfs_ioctl(dev_intf, USBDEVFS_DISCONNECT)) 74 except IOError as e: 75 if e.errno != errno.EACCES: 76 raise error.TestError( 77 'Got wrong error from ioctl: %s' % e.strerror) 78 else: 79 raise error.TestError('ioctl was incorrectly allowed') 80