linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] net/9p: Fix buffer overflow in USB transport layer
@ 2025-06-19 21:22 Dominique Martinet via B4 Relay
  2025-06-20  4:56 ` Greg Kroah-Hartman
  2025-06-20 10:02 ` kernel test robot
  0 siblings, 2 replies; 4+ messages in thread
From: Dominique Martinet via B4 Relay @ 2025-06-19 21:22 UTC (permalink / raw)
  To: Eric Van Hensbergen, Latchesar Ionkov, Christian Schoenebeck,
	Greg Kroah-Hartman, Michael Grzeschik
  Cc: stable, Yuhao Jiang, security, v9fs, linux-kernel,
	Dominique Martinet

From: Dominique Martinet <asmadeus@codewreck.org>

A buffer overflow vulnerability exists in the USB 9pfs transport layer
where inconsistent size validation between packet header parsing and
actual data copying allows a malicious USB host to overflow heap buffers.

The issue occurs because:
- usb9pfs_rx_header() validates only the declared size in packet header
- usb9pfs_rx_complete() uses req->actual (actual received bytes) for
memcpy

This allows an attacker to craft packets with small declared size
(bypassing validation) but large actual payload (triggering overflow
in memcpy).

Add validation in usb9pfs_rx_complete() to ensure req->actual does not
exceed the buffer capacity before copying data.

Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Closes: https://lkml.kernel.org/r/20250616132539.63434-1-danisjiang@gmail.com
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
---
Not actually tested, I'll try to find time to figure out how to run with
qemu for real this time...

Changes in v2:
- run through p9_client_cb() on error
- Link to v1: https://lore.kernel.org/r/20250616132539.63434-1-danisjiang@gmail.com
---
 net/9p/trans_usbg.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index 6b694f117aef296a66419fed5252305e7a1d0936..43078e0d4ca3f4063660f659d28452c81bef10b4 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -231,6 +231,8 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
 	struct f_usb9pfs *usb9pfs = ep->driver_data;
 	struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
 	struct p9_req_t *p9_rx_req;
+	unsigned int req_size = req->actual;
+	int status = REQ_STATUS_RCVD;
 
 	if (req->status) {
 		dev_err(&cdev->gadget->dev, "%s usb9pfs complete --> %d, %d/%d\n",
@@ -242,11 +244,19 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
 	if (!p9_rx_req)
 		return;
 
-	memcpy(p9_rx_req->rc.sdata, req->buf, req->actual);
+	if (req_size > p9_rx_req->rc.capacity) {
+		dev_err(&cdev->gadget->dev,
+			"%s received data size %u exceeds buffer capacity %zu\n",
+			ep->name, req_size, p9_rx_req->rc.capacity);
+		req_size = 0;
+		status = REQ_STATUS_ERROR;
+	}
 
-	p9_rx_req->rc.size = req->actual;
+	memcpy(p9_rx_req->rc.sdata, req->buf, req_size);
 
-	p9_client_cb(usb9pfs->client, p9_rx_req, REQ_STATUS_RCVD);
+	p9_rx_req->rc.size = req_sizel;
+
+	p9_client_cb(usb9pfs->client, p9_rx_req, status);
 	p9_req_put(usb9pfs->client, p9_rx_req);
 
 	complete(&usb9pfs->received);

---
base-commit: 74b4cc9b8780bfe8a3992c9ac0033bf22ac01f19
change-id: 20250620-9p-usb_overflow-25bfc5e9bef3

Best regards,
-- 
Dominique Martinet <asmadeus@codewreck.org>



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] net/9p: Fix buffer overflow in USB transport layer
  2025-06-19 21:22 [PATCH v2] net/9p: Fix buffer overflow in USB transport layer Dominique Martinet via B4 Relay
@ 2025-06-20  4:56 ` Greg Kroah-Hartman
  2025-06-22 20:33   ` Dominique Martinet
  2025-06-20 10:02 ` kernel test robot
  1 sibling, 1 reply; 4+ messages in thread
From: Greg Kroah-Hartman @ 2025-06-20  4:56 UTC (permalink / raw)
  To: asmadeus
  Cc: Eric Van Hensbergen, Latchesar Ionkov, Christian Schoenebeck,
	Michael Grzeschik, stable, Yuhao Jiang, security, v9fs,
	linux-kernel

On Fri, Jun 20, 2025 at 06:22:03AM +0900, Dominique Martinet via B4 Relay wrote:
> From: Dominique Martinet <asmadeus@codewreck.org>
> 
> A buffer overflow vulnerability exists in the USB 9pfs transport layer
> where inconsistent size validation between packet header parsing and
> actual data copying allows a malicious USB host to overflow heap buffers.
> 
> The issue occurs because:
> - usb9pfs_rx_header() validates only the declared size in packet header
> - usb9pfs_rx_complete() uses req->actual (actual received bytes) for
> memcpy
> 
> This allows an attacker to craft packets with small declared size
> (bypassing validation) but large actual payload (triggering overflow
> in memcpy).
> 
> Add validation in usb9pfs_rx_complete() to ensure req->actual does not
> exceed the buffer capacity before copying data.
> 
> Reported-by: Yuhao Jiang <danisjiang@gmail.com>
> Closes: https://lkml.kernel.org/r/20250616132539.63434-1-danisjiang@gmail.com
> Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
> Cc: stable@vger.kernel.org
> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
> ---
> Not actually tested, I'll try to find time to figure out how to run with
> qemu for real this time...
> 
> Changes in v2:
> - run through p9_client_cb() on error
> - Link to v1: https://lore.kernel.org/r/20250616132539.63434-1-danisjiang@gmail.com
> ---
>  net/9p/trans_usbg.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
> index 6b694f117aef296a66419fed5252305e7a1d0936..43078e0d4ca3f4063660f659d28452c81bef10b4 100644
> --- a/net/9p/trans_usbg.c
> +++ b/net/9p/trans_usbg.c
> @@ -231,6 +231,8 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
>  	struct f_usb9pfs *usb9pfs = ep->driver_data;
>  	struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
>  	struct p9_req_t *p9_rx_req;
> +	unsigned int req_size = req->actual;
> +	int status = REQ_STATUS_RCVD;
>  
>  	if (req->status) {
>  		dev_err(&cdev->gadget->dev, "%s usb9pfs complete --> %d, %d/%d\n",
> @@ -242,11 +244,19 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
>  	if (!p9_rx_req)
>  		return;
>  
> -	memcpy(p9_rx_req->rc.sdata, req->buf, req->actual);
> +	if (req_size > p9_rx_req->rc.capacity) {
> +		dev_err(&cdev->gadget->dev,
> +			"%s received data size %u exceeds buffer capacity %zu\n",
> +			ep->name, req_size, p9_rx_req->rc.capacity);

Do you want a broken device to be able to flood the kernel log?  You
might want to change this to dev_dbg() instead.



> +		req_size = 0;
> +		status = REQ_STATUS_ERROR;
> +	}
>  
> -	p9_rx_req->rc.size = req->actual;
> +	memcpy(p9_rx_req->rc.sdata, req->buf, req_size);
>  
> -	p9_client_cb(usb9pfs->client, p9_rx_req, REQ_STATUS_RCVD);
> +	p9_rx_req->rc.size = req_sizel;

Did this code build properly?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] net/9p: Fix buffer overflow in USB transport layer
  2025-06-19 21:22 [PATCH v2] net/9p: Fix buffer overflow in USB transport layer Dominique Martinet via B4 Relay
  2025-06-20  4:56 ` Greg Kroah-Hartman
@ 2025-06-20 10:02 ` kernel test robot
  1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2025-06-20 10:02 UTC (permalink / raw)
  To: Dominique Martinet via B4 Relay, Eric Van Hensbergen,
	Latchesar Ionkov, Christian Schoenebeck, Greg Kroah-Hartman,
	Michael Grzeschik
  Cc: llvm, oe-kbuild-all, stable, Yuhao Jiang, v9fs, linux-kernel,
	Dominique Martinet

Hi Dominique,

kernel test robot noticed the following build errors:

[auto build test ERROR on 74b4cc9b8780bfe8a3992c9ac0033bf22ac01f19]

url:    https://github.com/intel-lab-lkp/linux/commits/Dominique-Martinet-via-B4-Relay/net-9p-Fix-buffer-overflow-in-USB-transport-layer/20250620-052411
base:   74b4cc9b8780bfe8a3992c9ac0033bf22ac01f19
patch link:    https://lore.kernel.org/r/20250620-9p-usb_overflow-v2-1-026c6109c7a1%40codewreck.org
patch subject: [PATCH v2] net/9p: Fix buffer overflow in USB transport layer
config: i386-randconfig-004-20250620 (https://download.01.org/0day-ci/archive/20250620/202506201706.IUsC9LOI-lkp@intel.com/config)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250620/202506201706.IUsC9LOI-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202506201706.IUsC9LOI-lkp@intel.com/

All errors (new ones prefixed by >>):

>> net/9p/trans_usbg.c:257:23: error: use of undeclared identifier 'req_sizel'; did you mean 'req_size'?
     257 |         p9_rx_req->rc.size = req_sizel;
         |                              ^~~~~~~~~
         |                              req_size
   net/9p/trans_usbg.c:234:15: note: 'req_size' declared here
     234 |         unsigned int req_size = req->actual;
         |                      ^
   1 error generated.


vim +257 net/9p/trans_usbg.c

   228	
   229	static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
   230	{
   231		struct f_usb9pfs *usb9pfs = ep->driver_data;
   232		struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
   233		struct p9_req_t *p9_rx_req;
   234		unsigned int req_size = req->actual;
   235		int status = REQ_STATUS_RCVD;
   236	
   237		if (req->status) {
   238			dev_err(&cdev->gadget->dev, "%s usb9pfs complete --> %d, %d/%d\n",
   239				ep->name, req->status, req->actual, req->length);
   240			return;
   241		}
   242	
   243		p9_rx_req = usb9pfs_rx_header(usb9pfs, req->buf);
   244		if (!p9_rx_req)
   245			return;
   246	
   247		if (req_size > p9_rx_req->rc.capacity) {
   248			dev_err(&cdev->gadget->dev,
   249				"%s received data size %u exceeds buffer capacity %zu\n",
   250				ep->name, req_size, p9_rx_req->rc.capacity);
   251			req_size = 0;
   252			status = REQ_STATUS_ERROR;
   253		}
   254	
   255		memcpy(p9_rx_req->rc.sdata, req->buf, req_size);
   256	
 > 257		p9_rx_req->rc.size = req_sizel;
   258	
   259		p9_client_cb(usb9pfs->client, p9_rx_req, status);
   260		p9_req_put(usb9pfs->client, p9_rx_req);
   261	
   262		complete(&usb9pfs->received);
   263	}
   264	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] net/9p: Fix buffer overflow in USB transport layer
  2025-06-20  4:56 ` Greg Kroah-Hartman
@ 2025-06-22 20:33   ` Dominique Martinet
  0 siblings, 0 replies; 4+ messages in thread
From: Dominique Martinet @ 2025-06-22 20:33 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Eric Van Hensbergen, Latchesar Ionkov, Christian Schoenebeck,
	Michael Grzeschik, stable, Yuhao Jiang, security, v9fs,
	linux-kernel

Greg Kroah-Hartman wrote on Fri, Jun 20, 2025 at 06:56:24AM +0200:
> > -	memcpy(p9_rx_req->rc.sdata, req->buf, req->actual);
> > +	if (req_size > p9_rx_req->rc.capacity) {
> > +		dev_err(&cdev->gadget->dev,
> > +			"%s received data size %u exceeds buffer capacity %zu\n",
> > +			ep->name, req_size, p9_rx_req->rc.capacity);
> 
> Do you want a broken device to be able to flood the kernel log?  You
> might want to change this to dev_dbg() instead.

I realize I hadn't replied to this one -- I (still) consider 9p mounts
to be somewhat privileged/trusted, so I'm fine flooding kernel logs with
a broken device.
If the trust model changes (I've been askedto make 9p mountable by
non-root users... perhaps after we've caught up with syzcallers
reports but not holding my breath) then we can revisit this, but 9p IO
errors are rather badly behaved afaik (connection possibly never
recovers) so I'd rather the first error stands out.

> > -	p9_rx_req->rc.size = req->actual;
> > +	memcpy(p9_rx_req->rc.sdata, req->buf, req_size);
> >  
> > -	p9_client_cb(usb9pfs->client, p9_rx_req, REQ_STATUS_RCVD);
> > +	p9_rx_req->rc.size = req_sizel;
> 
> Did this code build properly?

Thanks/sorry for this one as well :/

-- 
Dominique

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-06-22 20:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-19 21:22 [PATCH v2] net/9p: Fix buffer overflow in USB transport layer Dominique Martinet via B4 Relay
2025-06-20  4:56 ` Greg Kroah-Hartman
2025-06-22 20:33   ` Dominique Martinet
2025-06-20 10:02 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).