⬢ DragonFlyBSD Kernel Audit
DF-5664 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/u4b/usb_mbuf.c
+++ b/sys/bus/u4b/usb_mbuf.c
@@ -59,14 +59,27 @@
 	struct usb_mbuf *m_ptr;
 	uint8_t *data_ptr;
 	void *free_ptr = NULL;
-	usb_size_t alloc_size;
+	size_t alloc_size;
 
 	/* align data */
 	block_size += ((-block_size) & (USB_HOST_ALIGN - 1));
 
 	if (nblocks && block_size) {
 
-		alloc_size = (block_size + sizeof(struct usb_mbuf)) * nblocks;
+		alloc_size = ((size_t)block_size + sizeof(struct usb_mbuf)) *
+		    (size_t)nblocks;
+
+		/*
+		 * The population loop below lays out nblocks headers plus
+		 * data areas at the full, untruncated stride.  Reject any
+		 * request whose backing byte count does not fit 32 bits;
+		 * otherwise the truncated kmalloc() would leave every data
+		 * pointer past the end of the allocation.  All current
+		 * callers are orders of magnitude below this bound.
+		 */
+		if (alloc_size > 0xFFFFFFFFU) {
+			goto done;
+		}
 
 		free_ptr = kmalloc(alloc_size, type, M_WAITOK | M_ZERO);