Skip to content

Commit c17536d

Browse files
Christoph Hellwiggregkh
authored andcommitted
usb: usbfs: stop using compat_alloc_user_space
Just switch the low-level routines to take kernel structures, and do the conversion from the compat to the native structure on that. Signed-off-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 6c9a9a8 commit c17536d

File tree

1 file changed

+69
-57
lines changed

1 file changed

+69
-57
lines changed

drivers/usb/core/devio.c

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,22 +1102,20 @@ static int usbdev_release(struct inode *inode, struct file *file)
11021102
return 0;
11031103
}
11041104

1105-
static int proc_control(struct usb_dev_state *ps, void __user *arg)
1105+
static int do_proc_control(struct usb_dev_state *ps,
1106+
struct usbdevfs_ctrltransfer *ctrl)
11061107
{
11071108
struct usb_device *dev = ps->dev;
1108-
struct usbdevfs_ctrltransfer ctrl;
11091109
unsigned int tmo;
11101110
unsigned char *tbuf;
11111111
unsigned wLength;
11121112
int i, pipe, ret;
11131113

1114-
if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1115-
return -EFAULT;
1116-
ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.bRequest,
1117-
ctrl.wIndex);
1114+
ret = check_ctrlrecip(ps, ctrl->bRequestType, ctrl->bRequest,
1115+
ctrl->wIndex);
11181116
if (ret)
11191117
return ret;
1120-
wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */
1118+
wLength = ctrl->wLength; /* To suppress 64k PAGE_SIZE warning */
11211119
if (wLength > PAGE_SIZE)
11221120
return -EINVAL;
11231121
ret = usbfs_increase_memory_usage(PAGE_SIZE + sizeof(struct urb) +
@@ -1129,52 +1127,52 @@ static int proc_control(struct usb_dev_state *ps, void __user *arg)
11291127
ret = -ENOMEM;
11301128
goto done;
11311129
}
1132-
tmo = ctrl.timeout;
1130+
tmo = ctrl->timeout;
11331131
snoop(&dev->dev, "control urb: bRequestType=%02x "
11341132
"bRequest=%02x wValue=%04x "
11351133
"wIndex=%04x wLength=%04x\n",
1136-
ctrl.bRequestType, ctrl.bRequest, ctrl.wValue,
1137-
ctrl.wIndex, ctrl.wLength);
1138-
if (ctrl.bRequestType & 0x80) {
1134+
ctrl->bRequestType, ctrl->bRequest, ctrl->wValue,
1135+
ctrl->wIndex, ctrl->wLength);
1136+
if (ctrl->bRequestType & 0x80) {
11391137
pipe = usb_rcvctrlpipe(dev, 0);
1140-
snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, NULL, 0);
1138+
snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0);
11411139

11421140
usb_unlock_device(dev);
1143-
i = usb_control_msg(dev, pipe, ctrl.bRequest,
1144-
ctrl.bRequestType, ctrl.wValue, ctrl.wIndex,
1145-
tbuf, ctrl.wLength, tmo);
1141+
i = usb_control_msg(dev, pipe, ctrl->bRequest,
1142+
ctrl->bRequestType, ctrl->wValue, ctrl->wIndex,
1143+
tbuf, ctrl->wLength, tmo);
11461144
usb_lock_device(dev);
11471145
snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE,
11481146
tbuf, max(i, 0));
1149-
if ((i > 0) && ctrl.wLength) {
1150-
if (copy_to_user(ctrl.data, tbuf, i)) {
1147+
if ((i > 0) && ctrl->wLength) {
1148+
if (copy_to_user(ctrl->data, tbuf, i)) {
11511149
ret = -EFAULT;
11521150
goto done;
11531151
}
11541152
}
11551153
} else {
1156-
if (ctrl.wLength) {
1157-
if (copy_from_user(tbuf, ctrl.data, ctrl.wLength)) {
1154+
if (ctrl->wLength) {
1155+
if (copy_from_user(tbuf, ctrl->data, ctrl->wLength)) {
11581156
ret = -EFAULT;
11591157
goto done;
11601158
}
11611159
}
11621160
pipe = usb_sndctrlpipe(dev, 0);
1163-
snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT,
1164-
tbuf, ctrl.wLength);
1161+
snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT,
1162+
tbuf, ctrl->wLength);
11651163

11661164
usb_unlock_device(dev);
1167-
i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest,
1168-
ctrl.bRequestType, ctrl.wValue, ctrl.wIndex,
1169-
tbuf, ctrl.wLength, tmo);
1165+
i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl->bRequest,
1166+
ctrl->bRequestType, ctrl->wValue, ctrl->wIndex,
1167+
tbuf, ctrl->wLength, tmo);
11701168
usb_lock_device(dev);
11711169
snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0);
11721170
}
11731171
if (i < 0 && i != -EPIPE) {
11741172
dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL "
11751173
"failed cmd %s rqt %u rq %u len %u ret %d\n",
1176-
current->comm, ctrl.bRequestType, ctrl.bRequest,
1177-
ctrl.wLength, i);
1174+
current->comm, ctrl->bRequestType, ctrl->bRequest,
1175+
ctrl->wLength, i);
11781176
}
11791177
ret = i;
11801178
done:
@@ -1184,30 +1182,37 @@ static int proc_control(struct usb_dev_state *ps, void __user *arg)
11841182
return ret;
11851183
}
11861184

1187-
static int proc_bulk(struct usb_dev_state *ps, void __user *arg)
1185+
static int proc_control(struct usb_dev_state *ps, void __user *arg)
1186+
{
1187+
struct usbdevfs_ctrltransfer ctrl;
1188+
1189+
if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1190+
return -EFAULT;
1191+
return do_proc_control(ps, &ctrl);
1192+
}
1193+
1194+
static int do_proc_bulk(struct usb_dev_state *ps,
1195+
struct usbdevfs_bulktransfer *bulk)
11881196
{
11891197
struct usb_device *dev = ps->dev;
1190-
struct usbdevfs_bulktransfer bulk;
11911198
unsigned int tmo, len1, pipe;
11921199
int len2;
11931200
unsigned char *tbuf;
11941201
int i, ret;
11951202

1196-
if (copy_from_user(&bulk, arg, sizeof(bulk)))
1197-
return -EFAULT;
1198-
ret = findintfep(ps->dev, bulk.ep);
1203+
ret = findintfep(ps->dev, bulk->ep);
11991204
if (ret < 0)
12001205
return ret;
12011206
ret = checkintf(ps, ret);
12021207
if (ret)
12031208
return ret;
1204-
if (bulk.ep & USB_DIR_IN)
1205-
pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f);
1209+
if (bulk->ep & USB_DIR_IN)
1210+
pipe = usb_rcvbulkpipe(dev, bulk->ep & 0x7f);
12061211
else
1207-
pipe = usb_sndbulkpipe(dev, bulk.ep & 0x7f);
1208-
if (!usb_maxpacket(dev, pipe, !(bulk.ep & USB_DIR_IN)))
1212+
pipe = usb_sndbulkpipe(dev, bulk->ep & 0x7f);
1213+
if (!usb_maxpacket(dev, pipe, !(bulk->ep & USB_DIR_IN)))
12091214
return -EINVAL;
1210-
len1 = bulk.len;
1215+
len1 = bulk->len;
12111216
if (len1 >= (INT_MAX - sizeof(struct urb)))
12121217
return -EINVAL;
12131218
ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb));
@@ -1218,8 +1223,8 @@ static int proc_bulk(struct usb_dev_state *ps, void __user *arg)
12181223
ret = -ENOMEM;
12191224
goto done;
12201225
}
1221-
tmo = bulk.timeout;
1222-
if (bulk.ep & 0x80) {
1226+
tmo = bulk->timeout;
1227+
if (bulk->ep & 0x80) {
12231228
snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0);
12241229

12251230
usb_unlock_device(dev);
@@ -1228,14 +1233,14 @@ static int proc_bulk(struct usb_dev_state *ps, void __user *arg)
12281233
snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, tbuf, len2);
12291234

12301235
if (!i && len2) {
1231-
if (copy_to_user(bulk.data, tbuf, len2)) {
1236+
if (copy_to_user(bulk->data, tbuf, len2)) {
12321237
ret = -EFAULT;
12331238
goto done;
12341239
}
12351240
}
12361241
} else {
12371242
if (len1) {
1238-
if (copy_from_user(tbuf, bulk.data, len1)) {
1243+
if (copy_from_user(tbuf, bulk->data, len1)) {
12391244
ret = -EFAULT;
12401245
goto done;
12411246
}
@@ -1254,6 +1259,15 @@ static int proc_bulk(struct usb_dev_state *ps, void __user *arg)
12541259
return ret;
12551260
}
12561261

1262+
static int proc_bulk(struct usb_dev_state *ps, void __user *arg)
1263+
{
1264+
struct usbdevfs_bulktransfer bulk;
1265+
1266+
if (copy_from_user(&bulk, arg, sizeof(bulk)))
1267+
return -EFAULT;
1268+
return do_proc_bulk(ps, &bulk);
1269+
}
1270+
12571271
static void check_reset_of_active_ep(struct usb_device *udev,
12581272
unsigned int epnum, char *ioctl_name)
12591273
{
@@ -2013,33 +2027,31 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg)
20132027
static int proc_control_compat(struct usb_dev_state *ps,
20142028
struct usbdevfs_ctrltransfer32 __user *p32)
20152029
{
2016-
struct usbdevfs_ctrltransfer __user *p;
2017-
__u32 udata;
2018-
p = compat_alloc_user_space(sizeof(*p));
2019-
if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) ||
2020-
get_user(udata, &p32->data) ||
2021-
put_user(compat_ptr(udata), &p->data))
2030+
struct usbdevfs_ctrltransfer ctrl;
2031+
u32 udata;
2032+
2033+
if (copy_from_user(&ctrl, p32, sizeof(*p32) - sizeof(compat_caddr_t)) ||
2034+
get_user(udata, &p32->data))
20222035
return -EFAULT;
2023-
return proc_control(ps, p);
2036+
ctrl.data = compat_ptr(udata);
2037+
return do_proc_control(ps, &ctrl);
20242038
}
20252039

20262040
static int proc_bulk_compat(struct usb_dev_state *ps,
20272041
struct usbdevfs_bulktransfer32 __user *p32)
20282042
{
2029-
struct usbdevfs_bulktransfer __user *p;
2030-
compat_uint_t n;
2043+
struct usbdevfs_bulktransfer bulk;
20312044
compat_caddr_t addr;
20322045

2033-
p = compat_alloc_user_space(sizeof(*p));
2034-
2035-
if (get_user(n, &p32->ep) || put_user(n, &p->ep) ||
2036-
get_user(n, &p32->len) || put_user(n, &p->len) ||
2037-
get_user(n, &p32->timeout) || put_user(n, &p->timeout) ||
2038-
get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data))
2046+
if (get_user(bulk.ep, &p32->ep) ||
2047+
get_user(bulk.len, &p32->len) ||
2048+
get_user(bulk.timeout, &p32->timeout) ||
2049+
get_user(addr, &p32->data))
20392050
return -EFAULT;
2040-
2041-
return proc_bulk(ps, p);
2051+
bulk.data = compat_ptr(addr);
2052+
return do_proc_bulk(ps, &bulk);
20422053
}
2054+
20432055
static int proc_disconnectsignal_compat(struct usb_dev_state *ps, void __user *arg)
20442056
{
20452057
struct usbdevfs_disconnectsignal32 ds;

0 commit comments

Comments
 (0)