From: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
Date: Wed, 30 Nov 2022 08:29:16 +0000 (+0100)
Subject: usb: gadget: dfu: Fix check of transfer direction
X-Git-Tag: v2025.01-rc5-pxa1908~1189^2~2
X-Git-Url: http://git.dujemihanovic.xyz/html/static/gitweb.css?a=commitdiff_plain;h=14dc0ab138988a8e45ffa086444ec8db48b3f103;p=u-boot.git

usb: gadget: dfu: Fix check of transfer direction

Commit fbce985e28eaca3af82afecc11961aadaf971a7e to fix CVE-2022-2347
blocks DFU usb requests.
The verification of the transfer direction was done by an equality
but it is a bit mask.

Signed-off-by: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
Reviewed-by: Fabio Estevam <festevam@denx.de>
Reviewed-by: Sultan Qasim Khan <sultan.qasimkhan@nccgroup.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Tested-by: Marek Vasut <marex@denx.de>
---

diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index 33ef62f8ba..44877df4ec 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -325,7 +325,7 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
 
 	switch (ctrl->bRequest) {
 	case USB_REQ_DFU_DNLOAD:
-		if (ctrl->bRequestType == USB_DIR_OUT) {
+		if (!(ctrl->bRequestType & USB_DIR_IN)) {
 			if (len == 0) {
 				f_dfu->dfu_state = DFU_STATE_dfuERROR;
 				value = RET_STALL;
@@ -337,7 +337,7 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
 		}
 		break;
 	case USB_REQ_DFU_UPLOAD:
-		if (ctrl->bRequestType == USB_DIR_IN) {
+		if (ctrl->bRequestType & USB_DIR_IN) {
 			f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
 			f_dfu->blk_seq_num = 0;
 			value = handle_upload(req, len);
@@ -436,7 +436,7 @@ static int state_dfu_dnload_idle(struct f_dfu *f_dfu,
 
 	switch (ctrl->bRequest) {
 	case USB_REQ_DFU_DNLOAD:
-		if (ctrl->bRequestType == USB_DIR_OUT) {
+		if (!(ctrl->bRequestType & USB_DIR_IN)) {
 			f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
 			f_dfu->blk_seq_num = w_value;
 			value = handle_dnload(gadget, len);
@@ -527,7 +527,7 @@ static int state_dfu_upload_idle(struct f_dfu *f_dfu,
 
 	switch (ctrl->bRequest) {
 	case USB_REQ_DFU_UPLOAD:
-		if (ctrl->bRequestType == USB_DIR_IN) {
+		if (ctrl->bRequestType & USB_DIR_IN) {
 			/* state transition if less data then requested */
 			f_dfu->blk_seq_num = w_value;
 			value = handle_upload(req, len);