Index: lib/msan/msan_interceptors.cc =================================================================== --- lib/msan/msan_interceptors.cc +++ lib/msan/msan_interceptors.cc @@ -1084,6 +1084,21 @@ return res; } +#if SANITIZER_FREEBSD +// On FreeBSD opendir() relies on strlen() to inspect internal structures +// so we have to intercept it. +INTERCEPTOR(__sanitizer_dirent *, opendir, const char *filename) { + ENSURE_MSAN_INITED(); + SIZE_T len = REAL(strlen)(filename); + CHECK_UNPOISONED(filename, len + 1); + InterceptorScope interceptor_scope; + return REAL(opendir)(filename); +} +#define MSAN_MAYBE_INTERCEPT_OPENDIR INTERCEPT_FUNCTION(opendir) +#else +#define MSAN_MAYBE_INTERCEPT_OPENDIR +#endif + class SignalHandlerScope { public: SignalHandlerScope() { @@ -1667,6 +1682,7 @@ INTERCEPT_FUNCTION(__cxa_atexit); INTERCEPT_FUNCTION(shmat); INTERCEPT_FUNCTION(fork); + MSAN_MAYBE_INTERCEPT_OPENDIR; inited = 1; } Index: lib/msan/tests/msan_test.cc =================================================================== --- lib/msan/tests/msan_test.cc +++ lib/msan/tests/msan_test.cc @@ -1225,6 +1225,16 @@ ASSERT_EQ(res, strlen(buf2) + 1); } +TEST(MemorySanitizer, opendir) { + DIR *dir = opendir("."); + closedir(dir); + + char name[10] = "."; + __msan_poison(name, sizeof(name)); + EXPECT_UMR(dir = opendir(name)); + closedir(dir); +} + TEST(MemorySanitizer, readdir) { DIR *dir = opendir("."); struct dirent *d = readdir(dir);