mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
bigint.c: fix buffer overflow in mpz_div_2exp with large shift
When right-shifting by more bits than the number contains, the loop condition `i < x->sz - digs` would underflow (since size_t is unsigned), causing out-of-bounds memory access. Fixed by checking if digs >= x->sz upfront and returning zero in that case, since shifting right by more bits than the number has always yields zero. Discovered via ClusterFuzz with input "7<<78<<-772". Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2099,12 +2099,18 @@ mpz_div_2exp(mpz_ctx_t *ctx, mpz_t *z, mpz_t *x, mrb_int e)
|
||||
else {
|
||||
size_t digs = e / DIG_SIZE;
|
||||
size_t bs = e % DIG_SIZE;
|
||||
mpz_t y;
|
||||
|
||||
size_t new_size = (digs >= x->sz) ? 1 : x->sz - digs;
|
||||
/* If shifting by more limbs than we have, result is zero */
|
||||
if (digs >= x->sz) {
|
||||
zero(z);
|
||||
return;
|
||||
}
|
||||
|
||||
mpz_t y;
|
||||
size_t new_size = x->sz - digs;
|
||||
mpz_init_temp(ctx, &y, new_size);
|
||||
mpz_realloc(ctx, &y, new_size);
|
||||
for (size_t i = 0; i < x->sz - digs; i++)
|
||||
for (size_t i = 0; i < new_size; i++)
|
||||
y.p[i] = x->p[i + digs];
|
||||
if (bs) {
|
||||
mpz_init_heap(ctx, z, new_size);
|
||||
|
||||
Reference in New Issue
Block a user