aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2022-03-03 09:22:41 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2022-03-03 09:24:24 +0000
commit8ed5bb59e913c61e61a4232e8221f35256f72ad2 (patch)
treee0c9ec8cb04ddb482537869e0ec951ad73ae8c98
parent87f6367f10614f58e5f93130b7be3364d2f83068 (diff)
downloadsrc-8ed5bb59e913c61e61a4232e8221f35256f72ad2.tar.gz
src-8ed5bb59e913c61e61a4232e8221f35256f72ad2.zip
usb(4): Factor out the usb_check_request() function.
No functional change. MFC after: 1 week Sponsored by: NVIDIA Networking
-rw-r--r--sys/dev/usb/usb_generic.c54
-rw-r--r--sys/dev/usb/usb_util.c51
-rw-r--r--sys/dev/usb/usb_util.h4
3 files changed, 57 insertions, 52 deletions
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index ab076d7234fb..fdbc35d47169 100644
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -2,7 +2,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2022 Hans Petter Selasky
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -869,54 +869,6 @@ ugen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di)
return (0);
}
-/*------------------------------------------------------------------------*
- * ugen_check_request
- *
- * Return values:
- * 0: Access allowed
- * Else: No access
- *------------------------------------------------------------------------*/
-static int
-ugen_check_request(struct usb_device *udev, struct usb_device_request *req)
-{
- struct usb_endpoint *ep;
- int error;
-
- /*
- * Avoid requests that would damage the bus integrity:
- */
- if (((req->bmRequestType == UT_WRITE_DEVICE) &&
- (req->bRequest == UR_SET_ADDRESS)) ||
- ((req->bmRequestType == UT_WRITE_DEVICE) &&
- (req->bRequest == UR_SET_CONFIG)) ||
- ((req->bmRequestType == UT_WRITE_INTERFACE) &&
- (req->bRequest == UR_SET_INTERFACE))) {
- /*
- * These requests can be useful for testing USB drivers.
- */
- error = priv_check(curthread, PRIV_DRIVER);
- if (error) {
- return (error);
- }
- }
- /*
- * Special case - handle clearing of stall
- */
- if (req->bmRequestType == UT_WRITE_ENDPOINT) {
- ep = usbd_get_ep_by_addr(udev, req->wIndex[0]);
- if (ep == NULL) {
- return (EINVAL);
- }
- if ((req->bRequest == UR_CLEAR_FEATURE) &&
- (UGETW(req->wValue) == UF_ENDPOINT_HALT)) {
- usbd_clear_data_toggle(udev, ep);
- }
- }
- /* TODO: add more checks to verify the interface index */
-
- return (0);
-}
-
int
ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur)
{
@@ -924,7 +876,7 @@ ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur)
uint16_t len;
uint16_t actlen;
- if (ugen_check_request(f->udev, &ur->ucr_request)) {
+ if (usb_check_request(f->udev, &ur->ucr_request)) {
return (EPERM);
}
len = UGETW(ur->ucr_request.wLength);
@@ -1165,7 +1117,7 @@ ugen_fs_copy_in(struct usb_fifo *f, uint8_t ep_index)
return (error);
}
}
- if (ugen_check_request(f->udev, req)) {
+ if (usb_check_request(f->udev, req)) {
xfer->error = USB_ERR_INVAL;
goto complete;
}
diff --git a/sys/dev/usb/usb_util.c b/sys/dev/usb/usb_util.c
index 8a85bf6506bb..b333180b6551 100644
--- a/sys/dev/usb/usb_util.c
+++ b/sys/dev/usb/usb_util.c
@@ -2,7 +2,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2022 Hans Petter Selasky
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -223,3 +223,52 @@ usb_make_str_desc(void *ptr, uint16_t max_len, const char *s)
}
return (totlen);
}
+
+/*------------------------------------------------------------------------*
+ * usb_check_request - prevent damaging USB requests
+ *
+ * Return values:
+ * 0: Access allowed
+ * Else: No access
+ *------------------------------------------------------------------------*/
+#if USB_HAVE_UGEN
+int
+usb_check_request(struct usb_device *udev, struct usb_device_request *req)
+{
+ struct usb_endpoint *ep;
+ int error;
+
+ /*
+ * Avoid requests that would damage the bus integrity:
+ */
+ if (((req->bmRequestType == UT_WRITE_DEVICE) &&
+ (req->bRequest == UR_SET_ADDRESS)) ||
+ ((req->bmRequestType == UT_WRITE_DEVICE) &&
+ (req->bRequest == UR_SET_CONFIG)) ||
+ ((req->bmRequestType == UT_WRITE_INTERFACE) &&
+ (req->bRequest == UR_SET_INTERFACE))) {
+ /*
+ * These requests can be useful for testing USB drivers.
+ */
+ error = priv_check(curthread, PRIV_DRIVER);
+ if (error)
+ return (error);
+ }
+
+ /*
+ * Special case - handle clearing of stall
+ */
+ if (req->bmRequestType == UT_WRITE_ENDPOINT) {
+ ep = usbd_get_ep_by_addr(udev, req->wIndex[0]);
+ if (ep == NULL)
+ return (EINVAL);
+ if ((req->bRequest == UR_CLEAR_FEATURE) &&
+ (UGETW(req->wValue) == UF_ENDPOINT_HALT))
+ usbd_clear_data_toggle(udev, ep);
+ }
+
+ /* TODO: add more checks to verify the interface index */
+
+ return (0);
+}
+#endif
diff --git a/sys/dev/usb/usb_util.h b/sys/dev/usb/usb_util.h
index 87e54d35150e..1bb20b86914b 100644
--- a/sys/dev/usb/usb_util.h
+++ b/sys/dev/usb/usb_util.h
@@ -29,8 +29,12 @@
#ifndef _USB_UTIL_H_
#define _USB_UTIL_H_
+struct usb_device;
+struct usb_device_request;
+
uint8_t usb_make_str_desc(void *ptr, uint16_t max_len, const char *s);
void usb_printbcd(char *p, uint16_t p_len, uint16_t bcd);
void usb_trim_spaces(char *p);
+int usb_check_request(struct usb_device *, struct usb_device_request *);
#endif /* _USB_UTIL_H_ */