musl - musl - an implementation of the standard library for Linux-based systems

index : musl
musl - an implementation of the standard library for Linux-based systems
summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2025年09月19日 18:35:19 -0400
committerRich Felker <dalias@aerifal.cx>2025年09月19日 18:35:19 -0400
commit0ccaf0572e9cccda2cced0f7ee659af4c1c6679a (patch)
treee023b5f4c8e5fe972514e948c7f06773937d5bb5
parent0b86d60badad6a69b37fc06d18b5763fbbf47b58 (diff)
downloadmusl-master.tar.gz
printf: fix buffer overflow in floating point decimal formattingHEAD master
commit f96e47a26102d537c29435f0abf9ec94676a030e introduced a new overflow past the end of the base-1e9 buffer for floating point to decimal conversion while fixing a different overflow below the start of the buffer. this bug has not been present in any release, and has not been analyzed in depth for security considerations. the root cause of the bug, incorrect size accounting for the mantissa, long predates the above commit, but was only exposed once the excessive offset causing overflow in the other direction was removed. the number of slots for expanding the mantissa was computed as if each slot could peel off at least 29 bits. this would be true if the mantissa were placed and expanded to the left of the radix point, but we don't do that because it would require repeated fmod and division. instead, we start the mantissa with 29 bits to the left of the radix point, so that they can be peeled off by conversion to integer and subtraction, followed by a multiplication by 1e9 to prepare for the next iteration. so while the first slot peels 29 bits, advancing to the next slot adds back somewhere between 20 and 21 bits: the length of the mantissa of 1e9. this means we need to account for a slot for every 8 bits of mantissa past the initial 29. add a comment to that effect and adjust the max_mant_slots formula.
Diffstat
-rw-r--r--src/stdio/vfprintf.c 4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index a68edabb..514a44dd 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -182,7 +182,9 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps)
{
int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG;
int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP;
- int max_mant_slots = (max_mant_dig+28)/29 + 1;
+ /* One slot for 29 bits left of radix point, a slot for every 29-21=8
+ * bits right of the radix point, and one final zero slot. */
+ int max_mant_slots = 1 + (max_mant_dig-29+7)/8 + 1;
int max_exp_slots = (max_exp+max_mant_dig+28+8)/9;
int bufsize = max_mant_slots + max_exp_slots;
uint32_t big[bufsize];
generated by cgit v1.2.1 (git 2.18.0) at 2025年09月23日 09:32:22 +0000

AltStyle によって変換されたページ (->オリジナル) /