diff options
| author | jvoisin | 2026-05-01 00:36:32 +0200 |
|---|---|---|
| committer | jvoisin | 2026-05-01 00:44:53 +0200 |
| commit | ddd22b2f533db9c0da0bb262fbafa51f67c8587e (patch) | |
| tree | d319dab03de20929f95ccf7f9bec8c428ab6a66b /include/wchar.h | |
| parent | d6105aba5fd791e8d3f069e771517cdb947b5604 (diff) | |
Fix strncat/wcsncat
Previously, no checks were done when __n <= __b, but strncat _appends_ after
existing content, making this a overly broad check check. For example, with an
8-byte buffer containing "12345\0", strncat(buf, "ABCD", 4) would have the
check skipped, but the result "12345ABCD\0" is 10 bytes, resulting in an
overflow.
This commit fixes this oversight, and adds a bunch of tests.
Diffstat (limited to '')
| -rw-r--r-- | include/wchar.h | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/include/wchar.h b/include/wchar.h index 2036245..4346023 100644 --- a/include/wchar.h +++ b/include/wchar.h | |||
| @@ -153,14 +153,12 @@ _FORTIFY_FN(wcsncat) wchar_t *wcsncat(wchar_t * _FORTIFY_POS0 __d, | |||
| 153 | size_t __b = __bos(__d, 0); | 153 | size_t __b = __bos(__d, 0); |
| 154 | size_t __sl, __dl; | 154 | size_t __sl, __dl; |
| 155 | 155 | ||
| 156 | if (__n > __b / sizeof(wchar_t)) { | 156 | __sl = wcslen(__s); |
| 157 | __sl = wcslen(__s); | 157 | __dl = wcslen(__d); |
| 158 | __dl = wcslen(__d); | 158 | if (__sl > __n) |
| 159 | if (__sl > __n) | 159 | __sl = __n; |
| 160 | __sl = __n; | 160 | if (__sl + __dl + 1 > __b / sizeof(wchar_t)) |
| 161 | if (__sl + __dl + 1 > __b / sizeof(wchar_t)) | 161 | __builtin_trap(); |
| 162 | __builtin_trap(); | ||
| 163 | } | ||
| 164 | return __orig_wcsncat(__d, __s, __n); | 162 | return __orig_wcsncat(__d, __s, __n); |
| 165 | } | 163 | } |
| 166 | 164 | ||
