Takashi Iwai c70519
From b870e73a56c4cccbec33224233eaf295839f228c Mon Sep 17 00:00:00 2001
Takashi Iwai c70519
From: Szymon Heidrich <szymon.heidrich@gmail.com>
Takashi Iwai c70519
Date: Wed, 11 Jan 2023 18:50:31 +0100
Takashi Iwai c70519
Subject: [PATCH] wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid
Takashi Iwai c70519
Git-commit: b870e73a56c4cccbec33224233eaf295839f228c
Takashi Iwai c70519
Patch-mainline: v6.2-rc5
Takashi Iwai c70519
References: git-fixes
Takashi Iwai c70519
Takashi Iwai c70519
Since resplen and respoffs are signed integers sufficiently
Takashi Iwai c70519
large values of unsigned int len and offset members of RNDIS
Takashi Iwai c70519
response will result in negative values of prior variables.
Takashi Iwai c70519
This may be utilized to bypass implemented security checks
Takashi Iwai c70519
to either extract memory contents by manipulating offset or
Takashi Iwai c70519
overflow the data buffer via memcpy by manipulating both
Takashi Iwai c70519
offset and len.
Takashi Iwai c70519
Takashi Iwai c70519
Additionally assure that sum of resplen and respoffs does not
Takashi Iwai c70519
overflow so buffer boundaries are kept.
Takashi Iwai c70519
Takashi Iwai c70519
Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
Takashi Iwai c70519
Signed-off-by: Szymon Heidrich <szymon.heidrich@gmail.com>
Takashi Iwai c70519
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Takashi Iwai c70519
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Takashi Iwai c70519
Link: https://lore.kernel.org/r/20230111175031.7049-1-szymon.heidrich@gmail.com
Takashi Iwai c70519
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai c70519
Takashi Iwai c70519
---
Takashi Iwai c70519
 drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
Takashi Iwai c70519
 1 file changed, 6 insertions(+), 13 deletions(-)
Takashi Iwai c70519
Takashi Iwai c70519
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
Takashi Iwai c70519
index 82a7458e01ae..bf72e5fd39cf 100644
Takashi Iwai c70519
--- a/drivers/net/wireless/rndis_wlan.c
Takashi Iwai c70519
+++ b/drivers/net/wireless/rndis_wlan.c
Takashi Iwai c70519
@@ -696,8 +696,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
Takashi Iwai c70519
 		struct rndis_query	*get;
Takashi Iwai c70519
 		struct rndis_query_c	*get_c;
Takashi Iwai c70519
 	} u;
Takashi Iwai c70519
-	int ret, buflen;
Takashi Iwai c70519
-	int resplen, respoffs, copylen;
Takashi Iwai c70519
+	int ret;
Takashi Iwai c70519
+	size_t buflen, resplen, respoffs, copylen;
Takashi Iwai c70519
 
Takashi Iwai c70519
 	buflen = *len + sizeof(*u.get);
Takashi Iwai c70519
 	if (buflen < CONTROL_BUFFER_SIZE)
Takashi Iwai c70519
@@ -732,22 +732,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
Takashi Iwai c70519
 
Takashi Iwai c70519
 		if (respoffs > buflen) {
Takashi Iwai c70519
 			/* Device returned data offset outside buffer, error. */
Takashi Iwai c70519
-			netdev_dbg(dev->net, "%s(%s): received invalid "
Takashi Iwai c70519
-				"data offset: %d > %d\n", __func__,
Takashi Iwai c70519
-				oid_to_string(oid), respoffs, buflen);
Takashi Iwai c70519
+			netdev_dbg(dev->net,
Takashi Iwai c70519
+				   "%s(%s): received invalid data offset: %zu > %zu\n",
Takashi Iwai c70519
+				   __func__, oid_to_string(oid), respoffs, buflen);
Takashi Iwai c70519
 
Takashi Iwai c70519
 			ret = -EINVAL;
Takashi Iwai c70519
 			goto exit_unlock;
Takashi Iwai c70519
 		}
Takashi Iwai c70519
 
Takashi Iwai c70519
-		if ((resplen + respoffs) > buflen) {
Takashi Iwai c70519
-			/* Device would have returned more data if buffer would
Takashi Iwai c70519
-			 * have been big enough. Copy just the bits that we got.
Takashi Iwai c70519
-			 */
Takashi Iwai c70519
-			copylen = buflen - respoffs;
Takashi Iwai c70519
-		} else {
Takashi Iwai c70519
-			copylen = resplen;
Takashi Iwai c70519
-		}
Takashi Iwai c70519
+		copylen = min(resplen, buflen - respoffs);
Takashi Iwai c70519
 
Takashi Iwai c70519
 		if (copylen > *len)
Takashi Iwai c70519
 			copylen = *len;
Takashi Iwai c70519
-- 
Takashi Iwai c70519
2.35.3
Takashi Iwai c70519