Bug 19414 - mbsrtowcs and wcsrtombs: UB and fail with large len
Summary: mbsrtowcs and wcsrtombs: UB and fail with large len
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: string (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-12-28 19:28 UTC by Alexander Cherepanov
Modified: 2020-11-18 20:33 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
mbsrtowcs and wcsrtombs fail with len=SIZE_MAX (187 bytes, text/plain)
2015-12-28 19:28 UTC, Alexander Cherepanov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Cherepanov 2015-12-28 19:28:27 UTC
Created attachment 8867 [details]
mbsrtowcs and wcsrtombs fail with len=SIZE_MAX

The len argument of the mbsrtowcs and wcsrtombs functions limits the number of elements stored into the destination array but it could be greater than the size of the array. Hence additions in the following codes fragments are invalid C (exhibit UB):

https://sourceware.org/git/?p=glibc.git;a=blob;f=wcsmbs/mbsrtowcs_l.c;h=d71934117d4e8aa894aa8d5f33ba2c308a7bf3d6;hb=HEAD#l107

 107       data.__outbuf = (unsigned char *) dst;
 108       data.__outbufend = data.__outbuf + len * sizeof (wchar_t);

https://sourceware.org/git/?p=glibc.git;a=blob;f=wcsmbs/wcsrtombs.c;h=ae303683383c3116a695bd0269c836a4f92c4cb9;hb=HEAD#l107

 107       data.__outbuf = (unsigned char *) dst;
 108       data.__outbufend = (unsigned char *) dst + len;

The functions also return wrong results wrongly return 0 when called with large len, e.g., with len=SIZE_MAX. The attached program prints "0 0" instead of "2 2".

Please note that fixing only wrong result is not enough, the root problem is invalid pointer arithmetic. See pr19411 for comparison.
Comment 1 Alex Sarkanski 2020-11-18 20:33:36 UTC
Potential error in the example attachment: 'state' variable (mbstate_t) should be zeroed between invocations of mbsrtowcs() and wcsrtombs().