git: 319414a926af - main - netmap: Handle overflow when computing ring sizes

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.current.scm
Message-ID <[email protected]>
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=319414a926af1515e2572f89f0636e5505e762d5

commit 319414a926af1515e2572f89f0636e5505e762d5
Author:     Mark Johnston <[email protected]>
AuthorDate: 2026-08-07 14:47:13 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-08-07 16:30:24 +0000

    netmap: Handle overflow when computing ring sizes
    
    PR:             297300
    Reported by:    Robert Morris
    Reported by:    syzkaller
    Reviewed by:    vmaffione
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58678
---
 sys/dev/netmap/netmap_mem2.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/sys/dev/netmap/netmap_mem2.c b/sys/dev/netmap/netmap_mem2.c
index 865a663da364..2d77acbbb06c 100644
--- a/sys/dev/netmap/netmap_mem2.c
+++ b/sys/dev/netmap/netmap_mem2.c
@@ -39,6 +39,7 @@
 #ifdef __FreeBSD__
 #include <sys/types.h>
 #include <sys/domainset.h>
+#include <sys/limits.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>		/* MALLOC_DEFINE */
 #include <sys/proc.h>
@@ -1992,6 +1993,7 @@ static int
 netmap_mem2_rings_create(struct netmap_mem_d *nmd, struct netmap_adapter *na)
 {
 	enum txrx t;
+	int error;
 
 	for_rx_tx(t) {
 		u_int i;
@@ -2011,11 +2013,20 @@ netmap_mem2_rings_create(struct netmap_mem_d *nmd, struct netmap_adapter *na)
 			if (netmap_debug & NM_DEBUG_MEM)
 				nm_prinf("creating %s", kring->name);
 			ndesc = kring->nkr_num_slots;
-			len = sizeof(struct netmap_ring) +
-				  ndesc * sizeof(struct netmap_slot);
+			if (ndesc >= UINT_MAX / sizeof(struct netmap_slot)) {
+				error = EINVAL;
+				goto cleanup;
+			}
+			len = ndesc * sizeof(struct netmap_slot);
+			if (len + sizeof(struct netmap_ring) < len) {
+				error = EINVAL;
+				goto cleanup;
+			}
+			len += sizeof(struct netmap_ring);
 			ring = netmap_ring_malloc(nmd, len);
 			if (ring == NULL) {
 				nm_prerr("Cannot allocate %s_ring", nm_txrx2str(t));
+				error = ENOMEM;
 				goto cleanup;
 			}
 			nm_prdis("txring at %p", ring);
@@ -2040,7 +2051,10 @@ netmap_mem2_rings_create(struct netmap_mem_d *nmd, struct netmap_adapter *na)
 				if (netmap_debug & NM_DEBUG_MEM)
 					nm_prinf("allocating buffers for %s", kring->name);
 				if (netmap_new_bufs(nmd, ring->slot, ndesc)) {
-					nm_prerr("Cannot allocate buffers for %s_ring", nm_txrx2str(t));
+					nm_prerr(
+					    "Cannot allocate buffers for %s_ring",
+					    nm_txrx2str(t));
+					error = ENOMEM;
 					goto cleanup;
 				}
 			} else {
@@ -2064,7 +2078,7 @@ cleanup:
 	 * to do the cleanup
 	 */
 
-	return ENOMEM;
+	return error;
 }
 
 static void
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.