--- 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 */