DF-2244 / fix.diff
--- sys/libkern/arc4random.c.orig 2026-10-17 14:02:28.000000000 +0000 +++ sys/libkern/arc4random.c 2026-10-17 14:08:00.000000000 +0000 @@ -143,18 +143,34 @@ { struct arc4_data *d = arc4_data_pcpu[mycpuid]; uint8_t *p = ptr; + size_t chunk; #if 0 /* No one call this function in ISR/ithread. */ crit_enter(); #endif - if (++(d->arc4_numruns) > ARC4_MAXRUNS || - time_uptime > d->arc4_nextreseed) - arc4_randomstir(d); + /* + * Charge the emitted keystream against the reseed budget (one + * run per 4 bytes, matching karc4random()) and cap the number + * of bytes generated under a single key, instead of charging + * one run per CALL and streaming an unbounded number of bytes + * from one RC4 key on a large request. + */ + while (len) { + chunk = len; + if (chunk > (size_t)ARC4_MAXRUNS * 4) + chunk = (size_t)ARC4_MAXRUNS * 4; - while (len--) - *p++ = arc4_randbyte(d); + if (++(d->arc4_numruns) > ARC4_MAXRUNS || + time_uptime > d->arc4_nextreseed) + arc4_randomstir(d); + + d->arc4_numruns += (int)(chunk / 4); + len -= chunk; + while (chunk--) + *p++ = arc4_randbyte(d); + } #if 0 crit_exit(); |