mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
bigint.c: fix buffer overflow in uadd with mismatched operand sizes
fix out-of-bounds read when adding bigints of different sizes. the unrolled loop accessed both operands up to the size of x without checking if y had enough limbs. when y->sz < x->sz, this caused reads beyond y's allocation. now use min(x->sz, y->sz) for the overlap region and handle remaining limbs from the larger operand separately. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -354,10 +354,11 @@ uadd(mpz_t *z, mpz_t *x, mpz_t *y)
|
||||
/* Core multi-limb addition with carry propagation */
|
||||
mp_dbl_limb c = 0;
|
||||
size_t i;
|
||||
size_t min_sz = (x->sz < y->sz) ? x->sz : y->sz;
|
||||
|
||||
/* Add overlapping limbs from both operands */
|
||||
/* 4x unrolled loop for better performance */
|
||||
for (i = 0; i + 4 <= x->sz; i += 4) {
|
||||
for (i = 0; i + 4 <= min_sz; i += 4) {
|
||||
c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];
|
||||
z->p[i] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
@@ -375,13 +376,20 @@ uadd(mpz_t *z, mpz_t *x, mpz_t *y)
|
||||
c >>= DIG_SIZE;
|
||||
}
|
||||
|
||||
/* Handle remaining elements */
|
||||
for (; i < x->sz; i++) {
|
||||
/* Handle remaining elements in overlap */
|
||||
for (; i < min_sz; i++) {
|
||||
c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];
|
||||
z->p[i] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
}
|
||||
|
||||
/* Add remaining limbs from x if it's larger */
|
||||
for (; i < x->sz; i++) {
|
||||
c += x->p[i];
|
||||
z->p[i] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
}
|
||||
|
||||
/* Add remaining limbs from larger operand */
|
||||
/* 4x unrolled loop for better performance */
|
||||
for (; i + 4 <= y->sz; i += 4) {
|
||||
|
||||
Reference in New Issue
Block a user