diff options
4 files changed, 52 insertions, 20 deletions
diff --git a/compiler-rt/lib/msan/lit_tests/Linux/glob_nomatch.cc b/compiler-rt/lib/msan/lit_tests/Linux/glob_nomatch.cc new file mode 100644 index 00000000000..0262034aec5 --- /dev/null +++ b/compiler-rt/lib/msan/lit_tests/Linux/glob_nomatch.cc @@ -0,0 +1,21 @@ +// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t %p +// RUN: %clangxx_msan -m64 -O3 %s -o %t && %t %p + +#include <assert.h> +#include <glob.h> +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char *argv[]) { + assert(argc == 2); + char buf[1024]; + snprintf(buf, sizeof(buf), "%s/%s", argv[1], "glob_test_root/*c"); + + glob_t globbuf; + int res = glob(buf, 0, 0, &globbuf); + assert(res == GLOB_NOMATCH); + assert(globbuf.gl_pathc == 0); + if (globbuf.gl_pathv == 0) + exit(0); + return 0; +} diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 867e998c88d..1616767351f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -738,18 +738,13 @@ INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { #define INIT_GETITIMER #endif - #if SANITIZER_INTERCEPT_GLOB -struct sanitizer_glob_t { - SIZE_T gl_pathc; - char **gl_pathv; -}; - -static void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) { +static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); // +1 for NULL pointer at the end. - COMMON_INTERCEPTOR_WRITE_RANGE( - ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); + if (pglob->gl_pathv) + COMMON_INTERCEPTOR_WRITE_RANGE( + ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { char *p = pglob->gl_pathv[i]; COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); @@ -758,32 +753,29 @@ static void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) { INTERCEPTOR(int, glob, const char *pattern, int flags, int (*errfunc)(const char *epath, int eerrno), - sanitizer_glob_t *pglob) { + __sanitizer_glob_t *pglob) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); int res = REAL(glob)(pattern, flags, errfunc, pglob); - if (res == 0) - unpoison_glob_t(ctx, pglob); + if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); return res; } INTERCEPTOR(int, glob64, const char *pattern, int flags, int (*errfunc)(const char *epath, int eerrno), - sanitizer_glob_t *pglob) { + __sanitizer_glob_t *pglob) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); int res = REAL(glob64)(pattern, flags, errfunc, pglob); - if (res == 0) - unpoison_glob_t(ctx, pglob); + if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); return res; } -#define INIT_GLOB \ - INTERCEPT_FUNCTION(glob); \ +#define INIT_GLOB \ + INTERCEPT_FUNCTION(glob); \ INTERCEPT_FUNCTION(glob64); -#else // SANITIZER_INTERCEPT_GLOB +#else // SANITIZER_INTERCEPT_GLOB #define INIT_GLOB -#endif // SANITIZER_INTERCEPT_GLOB - +#endif // SANITIZER_INTERCEPT_GLOB #if SANITIZER_INTERCEPT_WAIT // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 6e83efda204..05f81976981 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -58,6 +58,7 @@ #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID +#include <glob.h> #include <net/if_ppp.h> #include <netax25/ax25.h> #include <netipx/ipx.h> @@ -163,6 +164,10 @@ namespace __sanitizer { } #if SANITIZER_LINUX && !SANITIZER_ANDROID + int glob_nomatch = GLOB_NOMATCH; +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct); #if __WORDSIZE == 64 @@ -732,6 +737,11 @@ CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr); CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum); COMPILER_CHECK(IOC_SIZE(0x12345678) == _IOC_SIZE(0x12345678)); + +COMPILER_CHECK(sizeof(__sanitizer_glob_t) <= sizeof(glob_t)); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv); + #endif CHECK_TYPE_SIZE(addrinfo); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 96e3477032a..9b0ab0a1c87 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -181,6 +181,15 @@ namespace __sanitizer { }; #if SANITIZER_LINUX && !SANITIZER_ANDROID + struct __sanitizer_glob_t { + uptr gl_pathc; + char **gl_pathv; + }; + + extern int glob_nomatch; +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned struct_user_regs_struct_sz; extern unsigned struct_user_fpregs_struct_sz; extern unsigned struct_user_fpxregs_struct_sz; |

