Skip to content

Commit 6dfd5d9

Browse files
authored
Disable word-at-a-time optimization in mbsrtowcs when using ASan (#26678)
This optimization can cause ASan to report global-buffer-overflow because it reads up to 3 bytes past the end of the input string when checking for null terminators or non-ASCII characters. We already do this for several other musl functions such as strlen, stpcpy, and memchr. Also updates test_asan_no_error.c to include a regression check. Fixes: #26657
1 parent e42e640 commit 6dfd5d9

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

system/lib/libc/musl/src/multibyte/mbsrtowcs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs
3838
}
3939

4040
if (!ws) for (;;) {
41-
#ifdef __GNUC__
41+
/* XXX EMSCRIPTEN: add __has_feature check */
42+
#if defined(__GNUC__) && !__has_feature(address_sanitizer)
4243
typedef uint32_t __attribute__((__may_alias__)) w32;
4344
if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
4445
while (!(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) {
@@ -72,7 +73,8 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs
7273
*src = (const void *)s;
7374
return wn0;
7475
}
75-
#ifdef __GNUC__
76+
/* XXX EMSCRIPTEN: add __has_feature check */
77+
#if defined(__GNUC__) && !__has_feature(address_sanitizer)
7678
typedef uint32_t __attribute__((__may_alias__)) w32;
7779
if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
7880
while (wn>=5 && !(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) {

test/core/test_asan_no_error.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include <stdlib.h>
22
#include <string.h>
33
#include <stdio.h>
4+
#include <wchar.h>
5+
#include <locale.h>
46

57
int f(char *x) {
68
int z = *x;
@@ -17,6 +19,12 @@ int main() {
1719
strchr("hello", 'z');
1820
strlen("hello");
1921

22+
// setlocale is needed here otherwise mbsrtowcs takes the fast path
23+
// via strcpy.
24+
setlocale(LC_ALL, "en_US.UTF-8");
25+
const char* s = "abcd";
26+
mbsrtowcs(NULL, &s, 0, NULL);
27+
2028
printf("%d %d\n", f(x), y[9]);
2129
printf("done\n");
2230
return 0;

0 commit comments

Comments
 (0)