diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-02-24 06:35:17 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-02-24 06:35:17 -0800 |
commit | 4464034b7ccace6152299b746dcc0a964d16ad34 (patch) | |
tree | fa712eff8ce5f4e4a37a1e3f2fe013f96e620c5c /mpi/mpi.c | |
parent | 2617a362590670c1f2b61694be7295ac103adf9e (diff) | |
download | txr-4464034b7ccace6152299b746dcc0a964d16ad34.tar.gz txr-4464034b7ccace6152299b746dcc0a964d16ad34.tar.bz2 txr-4464034b7ccace6152299b746dcc0a964d16ad34.zip |
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.
Diffstat (limited to 'mpi/mpi.c')
-rw-r--r-- | mpi/mpi.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -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)) { |