This patch fixes a minor instance of undefined behavior in libdecnumber. It was discovered in the Rust bindings for libdecnumber (`dec`) using a custom version of MIRI that can execute foreign functions.
Within the function `decFloatFMA`, the pointer `lo->msd` is initialized to point to a byte array of size 56. ``` uByte acc[FMALEN]; /* for multiplied coefficient in BCD */ ... ub=acc+FMALEN-1; /* where lsd of result will go */ ... lo->msd=ub+1; lo->lsd=acc+FMALEN-1; ``` However, `lo->msd` is then offset in increments of 4, which leads to a read of two bytes beyond the size of `acc`. This patch switches to reading in increments of 2 instead of 4. Bootstrapped on x86_64-pc-linux-gnu with no regressions. libdecnumber/ChangeLog * decBasic.c: Increment `lo->msd` by 2 instead of 4 in `decFloatFMA` to avoid undefined behavior. --- libdecnumber/decBasic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libdecnumber/decBasic.c b/libdecnumber/decBasic.c index 6319f66b25d..3c8d71a2949 100644 --- a/libdecnumber/decBasic.c +++ b/libdecnumber/decBasic.c @@ -2023,6 +2023,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, uInt carry; /* +1 for ten's complement and during add */ uByte *ub, *uh, *ul; /* work */ uInt uiwork; /* for macros */ + uShort uswork; /* handle all the special values [any special operand leads to a */ /* special result] */ @@ -2252,7 +2253,7 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl, /* all done except for the special IEEE 754 exact-zero-result */ /* rule (see above); while testing for zero, strip leading */ /* zeros (which will save decFinalize doing it) */ - for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4; + for (; UBTOUS(lo->msd)==0 && lo->msd+1<lo->lsd;) lo->msd+=2; for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++; if (*lo->msd==0) { /* must be true zero (and diffsign) */ lo->sign=0; /* assume + */ -- 2.39.3 (Apple Git-145)