From 85e29c6edea1042eafbb8345ba0a7d805fa9b4bd Mon Sep 17 00:00:00 2001 Message-Id: <85e29c6edea1042eafbb8345ba0a7d805fa9b4bd.1714440817.git.mdw@distorted.org.uk> From: Mark Wooding Date: Fri, 22 Jun 2018 12:45:22 +0100 Subject: [PATCH] math/mpx.c (mpx_lsr): Fix pointer out-of-bounds bug. Organization: Straylight/Edgeware From: Mark Wooding If `n' is huge, and `av' is near the top of memory (e.g., in the top quarter, if we're using 32-bit digits) then `av + n' wraps around, and is consequently less than `avl', leading to all sorts of unfortunate behaviour. Noticed under `qemu-arm' on stretch, but generally applicable. --- math/mpx.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/math/mpx.c b/math/mpx.c index 18baf2f2..3983e7ca 100644 --- a/math/mpx.c +++ b/math/mpx.c @@ -545,15 +545,21 @@ MPX_SHIFTOP(lsr, { size_t nr = MPW_BITS - nb; mpw w; - av += nw; - w = av < avl ? *av++ : 0; - while (av < avl) { - mpw t; - if (dv >= dvl) goto done; - t = *av++; - *dv++ = MPW((w >> nb) | (t << nr)); - w = t; + if (nw >= avl - av) + w = 0; + else { + av += nw; + w = *av++; + + while (av < avl) { + mpw t; + if (dv >= dvl) goto done; + t = *av++; + *dv++ = MPW((w >> nb) | (t << nr)); + w = t; + } } + if (dv < dvl) { *dv++ = MPW(w >> nb); MPX_ZERO(dv, dvl); -- [mdw]