Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250922170821.GB1827@brightrain.aerifal.cx>
Date: Mon, 22 Sep 2025 13:08:21 -0400
From: Rich Felker <dalias@...c.org>
To: Georg Kotheimer <georg.kotheimer@...nkonzept.com>
Cc: musl@...ts.openwall.com
Subject: Re: Bug: Stack buffer overflow in printf on aarch64

On Sat, Sep 20, 2025 at 02:00:29PM +0200, Georg Kotheimer wrote:
> I am not knowledgeable enough to judge whether the math is correct, but
> from an empirical point of view the patch looks good, i.e. the overflow
> is gone.
> 
> Thanks for the explanation and promptly fixing the issue!

I stuck some debug outputs in to trace empirically what happens with
the old values, and miraculously it seems that z exactly hits the end
(withou twriting past it) with ieee-double or ld80 after 5 or 4 slots
respectively. So the bug only affected ld-quad archs.

I'll push the fix.

Rich


> On 20.09.25 00:52, Rich Felker wrote:
> > On Fri, Sep 19, 2025 at 06:25:03PM -0400, Rich Felker wrote:
> >> On Fri, Sep 19, 2025 at 10:20:54PM +0200, Georg Kotheimer wrote:
> >>> Hi,
> >>>
> >>> now I am a little confused, are you referring to the commit
> >>> f96e47a26102d537c29435f0abf9ec94676a030e ("printf: fix regression in
> >>> large double formatting on ld128 archs"), which is available on the
> >>> master branch? Or are you referring to some internal git that is not
> >>> visible to the public?
> >>>
> >>> Because if it's the former, it seems like the fix is insufficient, as I
> >>> just rechecked which commit I had checked out locally, it is
> >>> 0b86d60badad6a69b37fc06d18b5763fbbf47b58, which includes the
> >>> aforementioned fix. But still I observe the overflow I reported.
> >>
> >> Thank you so much for finding this. Indeed, the math is incorrect.
> >> max_mant_slots is computed as if each slot held at least 29 bits,
> >> which would be true if they were being expanded to the left of the
> >> radix point. But they're not. The initial y has 29 bits to the left of
> >> the radix point, but all the rest are to the right.
> >>
> >> At each stage of peeling bits, 29 bits are extracted to the next slot
> >> in *z, but the multiplication by 1000000000 adds back 21 bits to the
> >> mantissa of y. This nets only 8 bits being peeled.
> >>
> >> And indeed, using the formula 1+(ldbl_mant_dig-29+7)/8, representing 1
> >> slot for the initial 29 bits, counting off 29 bits initially peeled,
> >> and adding 8 per iteration, gives 12 as an upper bound, which agrees
> >> with the empirical result of 11 iterations for your worst-case value.
> >>
> >> (The upper bound is not sharp because multiplying by 1e9 doesn't
> >> actually add a "whole" 21 bits, but some fraction of the last bit.)
> >>
> >> I'll prepare a proposed patch.
> > 
> > See attached.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.