From b9870b413af28df524ac80b7e8b2c0e34122381b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 24 Feb 2021 06:35:17 -0800 Subject: mpi: bugfix: out-of-bounds access in or, xor. * mpi/mpi.c (mp_or, mp_xor): The main loop must only iterate up to the minimum number of digits between the two source operands, not the maximum number of digits, because otherwise it will access past the end of the shorter bignum's digit array. --- mpi/mpi.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/mpi/mpi.c b/mpi/mpi.c index 0d5e0beb..ad925c68 100644 --- a/mpi/mpi.c +++ b/mpi/mpi.c @@ -2087,13 +2087,14 @@ out: mp_err mp_or(mp_int *a, mp_int *b, mp_int *c) { mp_err res; - mp_size ix, extent = 0; + mp_size ix, extent, mindig; mp_digit *pa, *pb, *pc; mp_int tmp_a, tmp_b; ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); extent = MAX(USED(a), USED(b)); + mindig = MIN(USED(a), USED(b)); if (a == b) return mp_copy(a, c); @@ -2119,11 +2120,16 @@ mp_err mp_or(mp_int *a, mp_int *b, mp_int *c) goto out; for (pa = DIGITS(a), pb = DIGITS(b), pc = DIGITS(c), ix = 0; - ix < extent; ix++) + ix < mindig; ix++) { pc[ix] = pa[ix] | pb[ix]; } + if (ix < USED(a)) + s_mp_copy(pa + ix, pc + ix, USED(a) - ix); + else if (ix < USED(b)) + s_mp_copy(pb + ix, pc + ix, USED(b) - ix); + USED(c) = extent; if (ISNEG(a) || ISNEG(b)) { @@ -2146,7 +2152,7 @@ out: mp_err mp_xor(mp_int *a, mp_int *b, mp_int *c) { mp_err res; - mp_size ix, extent = 0; + mp_size ix, extent, mindig; mp_digit *pa, *pb, *pc; mp_int tmp_a, tmp_b; @@ -2158,6 +2164,7 @@ mp_err mp_xor(mp_int *a, mp_int *b, mp_int *c) } extent = MAX(USED(a), USED(b)); + mindig = MIN(USED(a), USED(b)); if (ISNEG(a)) { if ((res = mp_2comp(a, &tmp_a, extent)) != MP_OKAY) @@ -2180,11 +2187,16 @@ mp_err mp_xor(mp_int *a, mp_int *b, mp_int *c) goto out; for (pa = DIGITS(a), pb = DIGITS(b), pc = DIGITS(c), ix = 0; - ix < extent; ix++) + ix < mindig; ix++) { pc[ix] = pa[ix] ^ pb[ix]; } + if (ix < USED(a)) + s_mp_copy(pa + ix, pc + ix, USED(a) - ix); + else if (ix < USED(b)) + s_mp_copy(pb + ix, pc + ix, USED(b) - ix); + USED(c) = extent; if (ISNEG(a) ^ ISNEG(b)) { -- cgit v1.2.3