[PATCH v4 2/2] stdio-common: Fix buffer overflow in scanf %mc [BZ #34008]
Florian Weimer
fw@deneb.enyo.de
Mon Apr 6 09:00:26 GMT 2026
* Rocket Ma:
> * stdio-common/vfscanf-internal.c: When enlarging allocated buffer with
> format %mc or %mC, glibc allocates one byte less, leading to
> user-controlled one byte overflow. This commit fixes BZ #34008, or
> CVE-2026-5450. Unify newsize calculation of allocated buffer.
>
> Signed-off-by: Rocket Ma <marocketbd@gmail.com>
> ---
> stdio-common/vfscanf-internal.c | 74 ++++++++++++++++++++-------------
> 1 file changed, 46 insertions(+), 28 deletions(-)
>
> diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
> index 59fc8208aa..6bf2a55876 100644
> --- a/stdio-common/vfscanf-internal.c
> +++ b/stdio-common/vfscanf-internal.c
> @@ -265,6 +265,19 @@ char_buffer_add (struct char_buffer *buffer, CHAR_T ch)
> *buffer->current++ = ch;
> }
>
> +/* Calculate the result size of expanded char array in %ms, %mS,
> + %m[, %lm[, %mc or %mC. */
> +static __always_inline size_t
> +grow_to_fit (size_t oldsize, int need, int extra)
> +{
> + /* extra = 0 if %m[cC], %m[cC] always have positive width */
> + if ((extra && need < 0) || oldsize < need)
> + return oldsize * 2;
> + /* oldsize >= need:
> + grow requested capacity and `extra' byte for `\0' */
> + return oldsize + need + extra;
> +}
Thanks for working on this.
The last (extra) argument is constant. I'd suggest two functions with
descriptive names instead (maybe grow_to_fit_for_fixed for the %c
family, and grow_to_fit_with_null for the %s/%[] family that perform
null termination). The new functions probably shouldn't be inline, so
that the compiler can apply its heuristics.
As written, the interaction with the extra argument and a negative
need argument is not quite obvious from the function alone (code and
comments). The function seems correct because need (called width in
the caller) can only be -1 for the %s/%[] case, where extra is 1.
More information about the Libc-alpha
mailing list