[PATCH] printf_fp: Get rid of alloca.
Joe Simmons-Talbott
josimmon@redhat.com
Mon Aug 28 20:36:52 GMT 2023
Ping.
On Wed, Jul 05, 2023 at 01:19:38PM -0400, Joe Simmons-Talbott wrote:
> Replace unbounded alloca calls with scratch_buffers to avoid potential
> stack overflow.
> ---
> stdio-common/printf_fp.c | 59 ++++++++++++++++++++++++++++------------
> 1 file changed, 41 insertions(+), 18 deletions(-)
>
> diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
> index 6f22985ba1..9d6925a624 100644
> --- a/stdio-common/printf_fp.c
> +++ b/stdio-common/printf_fp.c
> @@ -28,6 +28,7 @@
> #include <gmp-mparam.h>
> #include <gmp.h>
> #include <ieee754.h>
> +#include <scratch_buffer.h>
> #include <stdlib/gmp-impl.h>
> #include <stdlib/longlong.h>
> #include <stdlib/fpioconst.h>
> @@ -181,8 +182,15 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
>
> /* Buffer in which we produce the output. */
> char *wbuffer = NULL;
> - /* Flag whether wbuffer and buffer are malloc'ed or not. */
> - int buffer_malloced = 0;
> +
> + struct scratch_buffer sbuf_frac;
> + scratch_buffer_init (&sbuf_frac);
> + struct scratch_buffer sbuf_tmp;
> + scratch_buffer_init (&sbuf_tmp);
> + struct scratch_buffer sbuf_scale;
> + scratch_buffer_init (&sbuf_scale);
> + struct scratch_buffer sbuf_wbuffer;
> + scratch_buffer_init (&sbuf_wbuffer);
>
> p.expsign = 0;
>
> @@ -268,9 +276,27 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
> + (GREATER_MANT_DIG / BITS_PER_MP_LIMB > 2
> ? 8 : 4))
> * sizeof (mp_limb_t);
> - p.frac = (mp_limb_t *) alloca (bignum_size);
> - p.tmp = (mp_limb_t *) alloca (bignum_size);
> - p.scale = (mp_limb_t *) alloca (bignum_size);
> +
> + if (!scratch_buffer_set_array_size (&sbuf_frac, 1, bignum_size))
> + {
> + __printf_buffer_mark_failed (buf);
> + goto free_mem_out;
> + }
> + p.frac = sbuf_frac.data;
> +
> + if (!scratch_buffer_set_array_size (&sbuf_tmp, 1, bignum_size))
> + {
> + __printf_buffer_mark_failed (buf);
> + goto free_mem_out;
> + }
> + p.tmp = sbuf_tmp.data;
> +
> + if (!scratch_buffer_set_array_size (&sbuf_scale, 1, bignum_size))
> + {
> + __printf_buffer_mark_failed (buf);
> + goto free_mem_out;
> + }
> + p.scale = sbuf_scale.data;
> }
>
> /* We now have to distinguish between numbers with positive and negative
> @@ -744,19 +770,13 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
> return;
> }
> size_t wbuffer_to_alloc = 2 + chars_needed;
> - buffer_malloced = ! __libc_use_alloca (wbuffer_to_alloc);
> - if (__builtin_expect (buffer_malloced, 0))
> + if (!scratch_buffer_set_array_size (&sbuf_wbuffer, 1, wbuffer_to_alloc))
> {
> - wbuffer = malloc (wbuffer_to_alloc);
> - if (wbuffer == NULL)
> - {
> - /* Signal an error to the caller. */
> - __printf_buffer_mark_failed (buf);
> - return;
> - }
> + /* Signal an error to the caller. */
> + __printf_buffer_mark_failed (buf);
> + goto free_mem_out;
> }
> - else
> - wbuffer = alloca (wbuffer_to_alloc);
> + wbuffer = sbuf_wbuffer.data;
> wcp = wstartp = wbuffer + 2; /* Let room for rounding. */
>
> /* Do the real work: put digits in allocated buffer. */
> @@ -1025,8 +1045,11 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
> __printf_buffer_pad (buf, info->pad, width);
> }
>
> - if (buffer_malloced)
> - free (wbuffer);
> +free_mem_out:
> + scratch_buffer_free (&sbuf_frac);
> + scratch_buffer_free (&sbuf_tmp);
> + scratch_buffer_free (&sbuf_scale);
> + scratch_buffer_free (&sbuf_wbuffer);
> }
>
> /* ASCII to localization translation. Multibyte version. */
> --
> 2.39.2
>
More information about the Libc-alpha
mailing list