git: 9157566d7ad5 - stable/13 - usb(4): Factor out the usb_check_request() function.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Thu, 10 Mar 2022 08:35:33 UTC
The branch stable/13 has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=9157566d7ad58560c6fa0ba6c2b88587688ee02c

commit 9157566d7ad58560c6fa0ba6c2b88587688ee02c
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-03-03 09:22:41 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-03-10 08:18:00 +0000

    usb(4): Factor out the usb_check_request() function.
    
    No functional change.
    
    Sponsored by:   NVIDIA Networking
    
    (cherry picked from commit 8ed5bb59e913c61e61a4232e8221f35256f72ad2)
---
 sys/dev/usb/usb_generic.c | 54 +++--------------------------------------------
 sys/dev/usb/usb_util.c    | 51 +++++++++++++++++++++++++++++++++++++++++++-
 sys/dev/usb/usb_util.h    |  4 ++++
 3 files changed, 57 insertions(+), 52 deletions(-)

diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index 65af2bd6979d..8c9d910ee92e 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
@@ -862,54 +862,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)
 {
@@ -917,7 +869,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);
@@ -1105,7 +1057,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_ */