usb: configfs: Implement secure attribute

Implement the secure attribute for locking USB access
from the gadget driver.

echo 1 > /sys/class/android_usb/android0/secure
will lock USB access and disable USB enumeration.

Change-Id: I9c7bcb27cfd4ce4f28520d938c604607ec6c2431
Moto-CRs-fixed: (CR)
Reviewed-on: https://gerrit.mot.com/1750996
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Zonghua Liu <a17671@motorola.com>
Reviewed-by: Yuecai Liu <liuyc20@motorola.com>
Reviewed-by: Jianqi Yang <yangj@motorola.com>
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1785337
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
This commit is contained in:
Ravi Vembu 2017-03-21 14:17:12 -05:00 • committed by Xiaojun Ji
commit 5d7a7200a4

View file

@ -96,6 +96,7 @@ struct gadget_info {
struct work_struct work;
struct device *dev;
#endif
bool secure;
};
static inline struct gadget_info *to_gadget_info(struct config_item *item)
@ -291,11 +292,19 @@ static int unregister_gadget(struct gadget_info *gi)
if (!gi->composite.gadget_driver.udc_name)
return -ENODEV;
if (gi->secure) {
gi->unbinding = false;
kfree(gi->composite.gadget_driver.udc_name);
gi->composite.gadget_driver.udc_name = NULL;
return 0;
}
gi->unbinding = true;
ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver);
if (ret)
if (ret) {
pr_err("unregister gadget failed, ret = %d\n", ret);
return ret;
}
gi->unbinding = false;
kfree(gi->composite.gadget_driver.udc_name);
gi->composite.gadget_driver.udc_name = NULL;
@ -318,6 +327,8 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
if (name[len - 1] == '\n')
name[len - 1] = '\0';
pr_debug("UDC store = %s\n", name);
mutex_lock(&gi->lock);
if (!strlen(name) || strcmp(name, "none") == 0) {
@ -331,10 +342,12 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
goto err;
}
gi->composite.gadget_driver.udc_name = name;
ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
if (ret) {
gi->composite.gadget_driver.udc_name = NULL;
goto err;
if (!gi->secure) {
ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
if (ret) {
gi->composite.gadget_driver.udc_name = NULL;
goto err;
}
}
#ifdef CONFIG_USB_CONFIGFS_UEVENT
schedule_work(&gi->work);
@ -1786,8 +1799,71 @@ out:
static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
static ssize_t secure_show(struct device *pdev, struct device_attribute *attr,
char *buf)
{
struct gadget_info *gi = dev_get_drvdata(pdev);
if (!gi)
return -ENODEV;
return scnprintf(buf, PAGE_SIZE, "%d\n", gi->secure);
}
static ssize_t secure_store(struct device *pdev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct gadget_info *gi = dev_get_drvdata(pdev);
unsigned long mode, r;
int ret;
if (!gi)
return -ENODEV;
r = kstrtoul(buf, 0, &mode);
if (r) {
dev_err(pdev, "Invalid value = %lu\n", mode);
return -EINVAL;
}
mode = !!mode;
if (mode == gi->secure)
return count;
mutex_lock(&gi->lock);
gi->secure = mode;
if (!gi->composite.gadget_driver.udc_name) {
mutex_unlock(&gi->lock);
return count;
}
pr_debug("Secure Store , UDC = %s, secure = %d\n",
gi->composite.gadget_driver.udc_name,
gi->secure);
if (gi->secure) {
ret = usb_gadget_unregister_driver(
&gi->composite.gadget_driver);
if (ret)
pr_err("Failed detaching UDC from gadget %d\n", ret);
} else {
ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
if (ret) {
gi->composite.gadget_driver.udc_name = NULL;
pr_err("Failed attaching UDC to gadget %d\n", ret);
}
}
mutex_unlock(&gi->lock);
return count;
}
static DEVICE_ATTR(secure, S_IRUGO | S_IWUSR, secure_show, secure_store);
static struct device_attribute *android_usb_attributes[] = {
&dev_attr_state,
&dev_attr_secure,
NULL
};