blob: 673c28c0ec8eb21295ce14faff111a31f4decfe4 [file] [log] [blame]
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import errno
import fcntl
import logging
import struct
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import device_jail_test_base
from autotest_lib.client.cros import device_jail_utils
# Definitions here are found in the uapi header linux/usbdevice_fs.h.
# struct usbdevfs_ioctl {
# int ifno;
# int ioctl_code;
# void __user *data;
# };
def usbdevfs_ioctl(ifno, ioctl_code):
return struct.pack('iiP', ifno, ioctl_code, 0)
# #define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl)
USBDEVFS_IOCTL = (3 << 30) + \
(ord('U') << 8) + \
18 + \
(struct.calcsize('iiP') << 16)
# #define USBDEVFS_DISCONNECT _IO('U', 22)
USBDEVFS_DISCONNECT = (ord('U') << 8) + 22
class security_DeviceJail_Lockdown(device_jail_test_base.DeviceJailTestBase):
"""
Simulate permission_broker locking the device down before letting us
open it, and then try to perform a privileged operation such as
disconnecting the kernel driver. If we are allowed to perform the
operation, something is broken.
"""
version = 1
def _find_device_with_interface(self):
usb_devices = device_jail_utils.get_usb_devices()
if not usb_devices:
error.TestNAError('No USB devices found')
for device in usb_devices:
if not device.children:
continue
for child in device.children:
if child.device_type != 'usb_interface':
continue
return (device.device_node,
child.attributes.asint('bInterfaceNumber'))
return (None, None)
def run_once(self):
dev_path, dev_intf = self._find_device_with_interface()
if not dev_path:
raise error.TestNAError('No suitable USB devices found')
logging.info('Using device %s, interface %d', dev_path, dev_intf)
with device_jail_utils.JailDevice(dev_path) as jail:
f = jail.expect_open(device_jail_utils.REQUEST_ALLOW_WITH_LOCKDOWN)
if not f:
raise error.TestError('Failed to open allowed jail')
with f as fd:
try:
fcntl.ioctl(fd, USBDEVFS_IOCTL,
usbdevfs_ioctl(dev_intf, USBDEVFS_DISCONNECT))
except IOError as e:
if e.errno != errno.EACCES:
raise error.TestError(
'Got wrong error from ioctl: %s' % e.strerror)
else:
raise error.TestError('ioctl was incorrectly allowed')