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)

Reply via email to