⬢ DragonFlyBSD Kernel Audit
DF-3786 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/video/bktr/bktr_core.c
+++ b/sys/dev/video/bktr/bktr_core.c
@@ -2079,6 +2079,12 @@
 		offset = (((struct eeProm *)arg)->offset);
 		count = (((struct eeProm *)arg)->count);
 		buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
+		/* DF-3785: eeProm.bytes is 256 bytes; unvalidated offset/count
+		 * used to overflow the 260-byte ioctl argument buffer. */
+		if (offset < 0 || count < 0 ||
+		    offset > (int)sizeof(((struct eeProm *)arg)->bytes) ||
+		    count > (int)sizeof(((struct eeProm *)arg)->bytes) - offset)
+			return (EINVAL);
 		if ( writeEEProm( bktr, offset, count, buf ) < 0 )
 			return( EIO );
 		break;
@@ -2087,6 +2093,12 @@
 		offset = (((struct eeProm *)arg)->offset);
 		count = (((struct eeProm *)arg)->count);
 		buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
+		/* DF-3785: the signed (offset+count) check in readEEProm() is
+		 * bypassable with a negative offset; validate here. */
+		if (offset < 0 || count < 0 ||
+		    offset > (int)sizeof(((struct eeProm *)arg)->bytes) ||
+		    count > (int)sizeof(((struct eeProm *)arg)->bytes) - offset)
+			return (EINVAL);
 		if ( readEEProm( bktr, offset, count, buf ) < 0 )
 			return( EIO );
 		break;
@@ -2095,6 +2107,11 @@
 		offset = (((struct eeProm *)arg)->offset);
 		count = (((struct eeProm *)arg)->count);
 		buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
+		/* DF-3786: signCard() ORs one bit per probed i2c address into
+		 * sig[x/8]; count must be bounded by sizeof(bytes)*8. */
+		if (count < 0 ||
+		    count > (int)sizeof(((struct eeProm *)arg)->bytes) * 8)
+			return (EINVAL);
 		if ( signCard( bktr, offset, count, buf ) < 0 )
 			return( EIO );
 		break;
--- a/sys/dev/video/bktr/bktr_card.c
+++ b/sys/dev/video/bktr/bktr_card.c
@@ -430,7 +430,7 @@
 		return( -1 );
 
 	max = (int)(bktr->card.eepromSize * EEPROMBLOCKSIZE);
-	if ( (offset + count) > max )
+	if ( offset < 0 || count < 0 || (offset + count) > max )
 		return( -1 );
 
 	/* set the start address */