summaryrefslogtreecommitdiffstats
path: root/mpi/mpi.c
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 /mpi/mpi.c
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.
Diffstat (limited to 'mpi/mpi.c')
-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)) {