stdlib: Fix right-justification in strfmon (bug 34510, CVE-2026-19499)

The memmove call did not take into account that __printf_buffer_pad
updated the buffer pointers.

Fixes commit e88b9f0e5c
("stdio-common: Convert vfprintf and related functions to buffers"),
which went into glibc 2.37.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit b090cf226f)
This commit is contained in:
Florian Weimer
2026-08-28 21:24:13 +02:00
committed by Aurelien Jarno
parent 893379d4ed
commit 6ad255db1d
3 changed files with 37 additions and 2 deletions
+1
View File
@@ -343,6 +343,7 @@ tests := \
tst-stdc_leading_zeros \
tst-stdc_trailing_ones \
tst-stdc_trailing_zeros \
tst-strfmon-bug34510 \
tst-strfmon_l \
tst-strfrom \
tst-strfrom-locale \
+3 -2
View File
@@ -549,7 +549,8 @@ __vstrfmon_l_buffer (struct __printf_buffer *buf, locale_t loc,
/* Now test whether the output width is filled. */
if (buf->write_ptr - startp < width)
{
size_t pad_width = width - (buf->write_ptr - startp);
size_t written_width = buf->write_ptr - startp;
size_t pad_width = width - written_width;
__printf_buffer_pad (buf, ' ', pad_width);
if (__printf_buffer_has_failed (buf))
/* Implies length check. */
@@ -558,7 +559,7 @@ __vstrfmon_l_buffer (struct __printf_buffer *buf, locale_t loc,
Otherwise move the field contents in place. */
if (!left)
{
memmove (startp + pad_width, startp, buf->write_ptr - startp);
memmove (startp + pad_width, startp, written_width);
memset (startp, ' ', pad_width);
}
}
+33
View File
@@ -0,0 +1,33 @@
/* Test handling of right-padding in strfmon (bug 34510, CVE-2026-19499).
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <monetary.h>
#include <errno.h>
#include <support/check.h>
#include <support/next_to_fault.h>
static int
do_test (void)
{
struct support_next_to_fault ntf = support_next_to_fault_allocate (100);
TEST_COMPARE (strfmon (ntf.buffer, ntf.length, "%100n", 1.23), -1);
TEST_COMPARE (errno, E2BIG);
return 0;
}
#include <support/test-driver.c>