summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-02-24 06:35:17 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-02-24 06:35:17 -0800
commit4464034b7ccace6152299b746dcc0a964d16ad34 (patch)
treefa712eff8ce5f4e4a37a1e3f2fe013f96e620c5c
parent2617a362590670c1f2b61694be7295ac103adf9e (diff)
downloadtxr-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.
-rw-r--r--mpi/mpi.c20
1 files 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)) {