summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-18 07:56:04 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-18 10:14:34 -0700
commitb97ffb72390bb8da611bf201bf4052d9ee8e850e (patch)
tree4ff9b8531d9fe3e6acaa0fe56d1e0d9666207e6b
parentcf5f21c8e7c54f0053c223e9ae6490b71d7314d3 (diff)
downloadtxr-b97ffb72390bb8da611bf201bf4052d9ee8e850e.tar.gz
txr-b97ffb72390bb8da611bf201bf4052d9ee8e850e.tar.bz2
txr-b97ffb72390bb8da611bf201bf4052d9ee8e850e.zip
mpi: avoid OOB pointer decr in two descending loops.
* mpi.c (s_mp_cmp): Rewrite loop as a for with a bottom test, and the increments in the usual place. ap and bp aren't decremented if the index is zero. Ironic to fix this, given that we march through the stack in the garbage collector. (s_mp_ispow2): Similar restructuring, with an additional guard around ix being set up to descend from the second-to-last digit.
-rw-r--r--mpi/mpi.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/mpi/mpi.c b/mpi/mpi.c
index e4122001..46ec3ddc 100644
--- a/mpi/mpi.c
+++ b/mpi/mpi.c
@@ -3824,13 +3824,13 @@ int s_mp_cmp(mp_int *a, mp_int *b)
mp_size ix = ua - 1;
mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix;
- while (ix < MP_SIZE_MAX) {
+ for (;; ix--, ap--, bp--) {
if (*ap > *bp)
return MP_GT;
else if (*ap < *bp)
return MP_LT;
-
- --ap; --bp; --ix;
+ if (ix == 0)
+ break;
}
return MP_EQ;
@@ -3871,14 +3871,16 @@ mp_size s_mp_ispow2(mp_int *v)
extra = s_highest_bit(d) - 1;
- ix = uv - 2;
- dp = DIGITS(v) + ix;
-
- while (ix < MP_SIZE_MAX - 1) {
- if (*dp)
- return MP_SIZE_MAX; /* not a power of two */
+ if (uv >= 2) {
+ ix = uv - 2;
+ dp = DIGITS(v) + ix;
- --dp; --ix;
+ for (;; ix--, dp--) {
+ if (*dp)
+ return MP_SIZE_MAX; /* not a power of two */
+ if (ix == 0)
+ break;
+ }
}
return ((uv - 1) * DIGIT_BIT) + extra;