[PATCH] dfu: bounds check USB upload and download sizes

Sultan Qasim Khan sultanqasim at gmail.com
Tue Nov 8 22:58:51 CET 2022


Also verify transfer directions match what is expected for the operation
type. Addresses memory corruption and disclosure vulnerability
CVE-2022-2347.

Signed-off-by: Sultan Qasim Khan <sultan.qasimkhan at nccgroup.com>
---
 drivers/usb/gadget/f_dfu.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index e9340ff5cb..4a7057c529 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -323,7 +323,7 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
 
 	switch (ctrl->bRequest) {
 	case USB_REQ_DFU_DNLOAD:
-		if (len == 0) {
+		if (len == 0 || len > DFU_USB_BUFSIZ || (ctrl->bRequestType & USB_DIR_IN)) {
 			f_dfu->dfu_state = DFU_STATE_dfuERROR;
 			value = RET_STALL;
 			break;
@@ -333,6 +333,11 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
 		value = handle_dnload(gadget, len);
 		break;
 	case USB_REQ_DFU_UPLOAD:
+		if (len > DFU_USB_BUFSIZ || (ctrl->bRequestType & USB_DIR_IN) != USB_DIR_IN) {
+			f_dfu->dfu_state = DFU_STATE_dfuERROR;
+			value = RET_STALL;
+			break;
+		}
 		f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
 		f_dfu->blk_seq_num = 0;
 		value = handle_upload(req, len);
@@ -428,6 +433,11 @@ static int state_dfu_dnload_idle(struct f_dfu *f_dfu,
 
 	switch (ctrl->bRequest) {
 	case USB_REQ_DFU_DNLOAD:
+		if (len > DFU_USB_BUFSIZ || (ctrl->bRequestType & USB_DIR_IN)) {
+			f_dfu->dfu_state = DFU_STATE_dfuERROR;
+			value = RET_STALL;
+			break;
+		}
 		f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
 		f_dfu->blk_seq_num = w_value;
 		value = handle_dnload(gadget, len);
@@ -515,6 +525,11 @@ static int state_dfu_upload_idle(struct f_dfu *f_dfu,
 
 	switch (ctrl->bRequest) {
 	case USB_REQ_DFU_UPLOAD:
+		if (len > DFU_USB_BUFSIZ || (ctrl->bRequestType & USB_DIR_IN) != USB_DIR_IN) {
+			f_dfu->dfu_state = DFU_STATE_dfuERROR;
+			value = RET_STALL;
+			break;
+		}
 		/* state transition if less data then requested */
 		f_dfu->blk_seq_num = w_value;
 		value = handle_upload(req, len);
-- 
2.31.1



More information about the U-Boot mailing list