glibc/wcsmbs
Siddhesh Poyarekar 9bcd12d223 wcrtomb: Make behavior POSIX compliant
The GNU implementation of wcrtomb assumes that there are at least
MB_CUR_MAX bytes available in the destination buffer passed to wcrtomb
as the first argument.  This is not compatible with the POSIX
definition, which only requires enough space for the input wide
character.

This does not break much in practice because when users supply buffers
smaller than MB_CUR_MAX (e.g. in ncurses), they compute and dynamically
allocate the buffer, which results in enough spare space (thanks to
usable_size in malloc and padding in alloca) that no actual buffer
overflow occurs.  However when the code is built with _FORTIFY_SOURCE,
it runs into the hard check against MB_CUR_MAX in __wcrtomb_chk and
hence fails.  It wasn't evident until now since dynamic allocations
would result in wcrtomb not being fortified but since _FORTIFY_SOURCE=3,
that limitation is gone, resulting in such code failing.

To fix this problem, introduce an internal buffer that is MB_LEN_MAX
long and use that to perform the conversion and then copy the resultant
bytes into the destination buffer.  Also move the fortification check
into the main implementation, which checks the result after conversion
and aborts if the resultant byte count is greater than the destination
buffer size.

One complication is that applications that assume the MB_CUR_MAX
limitation to be gone may not be able to run safely on older glibcs if
they use static destination buffers smaller than MB_CUR_MAX; dynamic
allocations will always have enough spare space that no actual overruns
will occur.  One alternative to fixing this is to bump symbol version to
prevent them from running on older glibcs but that seems too strict a
constraint.  Instead, since these users will only have made this
decision on reading the manual, I have put a note in the manual warning
them about the pitfalls of having static buffers smaller than
MB_CUR_MAX and running them on older glibc.

Benchmarking:

The wcrtomb microbenchmark shows significant increases in maximum
execution time for all locales, ranging from 10x for ar_SA.UTF-8 to
1.5x-2x for nearly everything else.  The mean execution time however saw
practically no impact, with some results even being quicker, indicating
that cache locality has a much bigger role in the overhead.

Given that the additional copy uses a temporary buffer inside wcrtomb,
it's likely that a hot path will end up putting that buffer (which is
responsible for the additional overhead) in a similar place on stack,
giving the necessary cache locality to negate the overhead.  However in
situations where wcrtomb ends up getting called at wildly different
spots on the call stack (or is on different call stacks, e.g. with
threads or different execution contexts) and is still a hotspot, the
performance lag will be visible.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2022-05-13 19:15:46 +05:30
..
bits debug: Synchronize feature guards in fortified functions [BZ #28746] 2022-01-12 23:34:48 +05:30
btowc.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
c16rtomb.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
c32rtomb.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
Depend Update. 2000-09-06 22:15:07 +00:00
isoc99_fwscanf.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
isoc99_swscanf.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
isoc99_vfwscanf.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
isoc99_vswscanf.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
isoc99_vwscanf.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
isoc99_wscanf.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
Makefile Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbrlen.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbrtoc16.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbrtoc32.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbrtowc.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbsinit.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbsnrtowcs.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbsrtowcs_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
mbsrtowcs.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-char-types.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcpcpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcpncpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcscat.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcschr.c Add wcschr test cases 2011-10-23 14:14:26 -04:00
test-wcschrnul.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcscmp.c Move wide char tests to wcsmbs directory 2011-09-08 18:01:07 -04:00
test-wcscpy.c Add tests for wcsrchr and wcscpy 2011-12-17 14:14:58 -05:00
test-wcscspn.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcslen.c Add wcslen test cases 2011-10-23 14:11:50 -04:00
test-wcsncat.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcsncmp.c Use correct signedness in wcsncmp 2015-04-13 21:25:04 +02:00
test-wcsncpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcsnlen.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcspbrk.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wcsrchr.c Add tests for wcsrchr and wcscpy 2011-12-17 14:14:58 -05:00
test-wcsspn.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wmemchr.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
test-wmemcmp.c Move wide char tests to wcsmbs directory 2011-09-08 18:01:07 -04:00
test-wmemset.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-btowc.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-c16-surrogate.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-c16c32-1.c Add #include <stdint.h> for uint[32|64]_t usage (except installed headers). 2013-05-16 11:32:54 -05:00
tst-c32-state.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-fgetwc-after-eof.c [BZ 1190] Make EOF sticky in stdio. 2018-03-13 08:31:56 -04:00
tst-mbrtowc2.c Prefer https for Sourceware links 2017-11-16 11:49:26 +05:30
tst-mbrtowc.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-mbsrtowcs.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-mbstowcs.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wchar-h.c Update wcsmbs tests to use the support test driver 2017-04-04 18:05:20 -03:00
tst-wcpncpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wcrtomb.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wcsnlen.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wcstod-nan-locale.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wcstod-nan-sign.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wcstod-round.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wcstof.c Update wcsmbs tests to use the support test driver 2017-04-04 18:05:20 -03:00
tst-wcstol-locale.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
tst-wprintf-binary.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
uchar.h Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
Versions Add _Float32 function aliases. 2017-12-07 00:48:31 +00:00
wchar.h Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcpcpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcpncpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcrtomb.c wcrtomb: Make behavior POSIX compliant 2022-05-13 19:15:46 +05:30
wcsatcliff.c Fix handling of tail bytes of buffer in SSE2/SSSE3 x86-64 version strn{,case}cmp 2010-10-03 22:10:30 -04:00
wcscasecmp_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcscasecmp.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcscat.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcschr.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcschrnul.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcscmp.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcscoll_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcscoll.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcscpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcscspn.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsdup.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcslen.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsmbs-tst1.c Add dependencies on needed locales in each subdir tests (bug 18969) 2015-10-12 15:18:08 +02:00
wcsmbsload.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsmbsload.h Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsncase_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsncase.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsncat.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsncmp.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsncpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsnlen.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsnrtombs.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcspbrk.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsrchr.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsrtombs.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsspn.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsstr.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstod_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstod_nan.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstod.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstof_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstof_nan.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstof.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstok.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstol_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstol.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstold_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstold_nan.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstold.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstoll_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstoll.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstoul_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstoul.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstoull_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcstoull.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcswidth.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsxfrm_l.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcsxfrm.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wctob.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcwidth.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wcwidth.h Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wmemchr.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wmemcmp.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wmemcpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wmemmove.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wmempcpy.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00
wmemset.c Update copyright dates with scripts/update-copyrights 2022-01-01 11:40:24 -08:00