[PATCH] hw/net/rtl8139: Fix integer overflow in rtl8139_write_buffer

orion cai posted 1 patch 1 day, 4 hours ago
Failed in applying to current master (apply log)
hw/net/rtl8139.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
[PATCH] hw/net/rtl8139: Fix integer overflow in rtl8139_write_buffer
Posted by orion cai 1 day, 4 hours ago
From d1781652dc7039b2ac92fa80695091b97dbf1918 Mon Sep 17 00:00:00 2001
From: orion cai <orion@orions-MacBook-Air.local>
Date: Sat, 24 Jan 2026 11:19:17 +0800
Subject: [PATCH] hw/net/rtl8139: Fix integer overflow in rtl8139_write_buffer

Fix integer overflow vulnerability in rtl8139_write_buffer() that could allow
a malicious guest to bypass DMA bounds checks and write to arbitrary memory
locations.

The vulnerability occurs when:
- RxBufAddr is near UINT_MAX (e.g., 0xFFFF0000)
- size is a moderate value (e.g., 0x20000)
- The addition RxBufAddr + size overflows and wraps to a small value
- This bypasses the bounds check (s->RxBufAddr + size > s->RxBufferSize)

Fix uses subtraction instead of addition for the bounds check and applies
modulo to each term individually before computing the wrapped position to
prevent overflow in all code paths.

Signed-off-by: orionhubble@163.com
---
 hw/net/rtl8139.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 9fd00574d2..41b8407acc 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -745,9 +745,16 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
 {
     PCIDevice *d = PCI_DEVICE(s);
 
-    if (s->RxBufAddr + size > s->RxBufferSize)
+    if (size < 0 || s->RxBufAddr > s->RxBufferSize - (uint32_t)size)
     {
-        int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize);
+        /* Calculate wrapped position safely without overflow.
+         * Use modulo on each term to prevent overflow.
+         * RxBufferSize is always a power of 2, so MOD2 is safe. */
+        int wrapped = MOD2((uint32_t)s->RxBufAddr, s->RxBufferSize) +
+                    MOD2((uint32_t)size, s->RxBufferSize);
+        if (wrapped >= s->RxBufferSize) {
+            wrapped -= s->RxBufferSize;
+        }
 
         /* write packet data */
         if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s)))
-- 
2.50.1 (Apple Git-155)
Re: [PATCH] hw/net/rtl8139: Fix integer overflow in rtl8139_write_buffer
Posted by Mohamed Mediouni 23 hours ago

> On 24. Jan 2026, at 04:33, orion cai <orion@orions-MacBook-Air.local> wrote:
> 
> From d1781652dc7039b2ac92fa80695091b97dbf1918 Mon Sep 17 00:00:00 2001
> From: orion cai <orion@orions-MacBook-Air.local>
> Date: Sat, 24 Jan 2026 11:19:17 +0800
> Subject: [PATCH] hw/net/rtl8139: Fix integer overflow in rtl8139_write_buffer
> 
> Fix integer overflow vulnerability in rtl8139_write_buffer() that could allow
> a malicious guest to bypass DMA bounds checks and write to arbitrary memory
> locations.
> 
> The vulnerability occurs when:
> - RxBufAddr is near UINT_MAX (e.g., 0xFFFF0000)
> - size is a moderate value (e.g., 0x20000)
> - The addition RxBufAddr + size overflows and wraps to a small value
> - This bypasses the bounds check (s->RxBufAddr + size > s->RxBufferSize)
> 
> Fix uses subtraction instead of addition for the bounds check and applies
> modulo to each term individually before computing the wrapped position to
> prevent overflow in all code paths.
> 
> Signed-off-by: orionhubble@163.com

Hi,

Your Git client is misconfigured and didn’t send with a proper email address.

And your Signed-off-by isn’t in the proper format, see https://www.qemu.org/docs/master/devel/code-provenance.html

Thank you,
-Mohamed
> ---
> hw/net/rtl8139.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
> index 9fd00574d2..41b8407acc 100644
> --- a/hw/net/rtl8139.c
> +++ b/hw/net/rtl8139.c
> @@ -745,9 +745,16 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
> {
>     PCIDevice *d = PCI_DEVICE(s);
> 
> -    if (s->RxBufAddr + size > s->RxBufferSize)
> +    if (size < 0 || s->RxBufAddr > s->RxBufferSize - (uint32_t)size)
>     {
> -        int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize);
> +        /* Calculate wrapped position safely without overflow.
> +         * Use modulo on each term to prevent overflow.
> +         * RxBufferSize is always a power of 2, so MOD2 is safe. */
> +        int wrapped = MOD2((uint32_t)s->RxBufAddr, s->RxBufferSize) +
> +                    MOD2((uint32_t)size, s->RxBufferSize);
> +        if (wrapped >= s->RxBufferSize) {
> +            wrapped -= s->RxBufferSize;
> +        }
> 
>         /* write packet data */
>         if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s)))
> -- 
> 2.50.1 (Apple Git-155)
> 
>