fortify-headers

standalone fortify-source implementation
git clone git://git.2f30.org/fortify-headers
Log | Files | Refs | README | LICENSE

commit 9b796691eb794e9f5279886e917c028a09f8a728
parent ff82ffbc74d82091527449e31fe351d15830f716
Author: info@mobile-stream.com <info@mobile-stream.com>
Date:   Wed,  6 Mar 2019 16:28:48 +0300

wctomb, wcrtomb: guard slow/trap path with MB_LEN_MAX

This allows the compiler to optimize out the slow/trap path at all
for the typical correct code:

char buf[MB_LEN_MAX];
r = wctomb(buf, c);

The change tries to keep the "unknown object size" case handling in
wcrtomb() as is even if it seems redundant and not helping (we copy
__buf to possibly undersized __s in any case) and inconsistent with
wctomb() (where we let the original library method itself overwrite
the possibly undersized __s).

Diffstat:
Minclude/wchar.h | 11+++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/include/wchar.h b/include/wchar.h @@ -111,15 +111,14 @@ _FORTIFY_FN(mbstowcs) size_t mbstowcs(wchar_t *__ws, const char *__s, size_t __w _FORTIFY_FN(wcrtomb) size_t wcrtomb(char *__s, wchar_t __w, mbstate_t *__st) { - char __buf[MB_LEN_MAX]; - size_t __b = __builtin_object_size(__s, 0); - size_t __r; + if (__s && MB_LEN_MAX > __builtin_object_size(__s, 2)) { + char __buf[MB_LEN_MAX]; + size_t __r; - if (__s) { __r = __orig_wcrtomb(__buf, __w, __st); if (__r == (size_t)-1) return __r; - if (__r > __b) + if (__r > __builtin_object_size(__s, 0)) __builtin_trap(); __builtin_memcpy(__s, __buf, __r); return __r; @@ -218,7 +217,7 @@ _FORTIFY_FN(wctomb) int wctomb(char *__s, wchar_t __w) { size_t __b = __builtin_object_size(__s, 0); - if (__s && MB_CUR_MAX > __b) + if (__s && MB_LEN_MAX > __b && MB_CUR_MAX > __b) __builtin_trap(); return __orig_wctomb(__s, __w); }