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
commitb9870b413af28df524ac80b7e8b2c0e34122381b (patch)
treefa712eff8ce5f4e4a37a1e3f2fe013f96e620c5c
parent83f855f96cfb067ee8bfed1fb89003070f9f7eea (diff)
downloadtxr-b9870b413af28df524ac80b7e8b2c0e34122381b.tar.gz
txr-b9870b413af28df524ac80b7e8b2c0e34122381b.tar.bz2
txr-b9870b413af28df524ac80b7e8b2c0e34122381b.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)) {