diff options
Diffstat (limited to 'lib/msan/tests/msan_test.cc')
-rw-r--r-- | lib/msan/tests/msan_test.cc | 156 |
1 files changed, 130 insertions, 26 deletions
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 554265da6aa9..1c5fc5f7f1e3 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -21,13 +21,25 @@ #include "sanitizer/allocator_interface.h" #include "sanitizer/msan_interface.h" +#if defined(__FreeBSD__) +# define _KERNEL // To declare 'shminfo' structure. +# include <sys/shm.h> +# undef _KERNEL +extern "C" { +// <sys/shm.h> doesn't declare these functions in _KERNEL mode. +void *shmat(int, const void *, int); +int shmget(key_t, size_t, int); +int shmctl(int, int, struct shmid_ds *); +int shmdt(const void *); +} +#endif + #include <inttypes.h> #include <stdlib.h> #include <stdarg.h> #include <stdio.h> #include <wchar.h> #include <math.h> -#include <malloc.h> #include <arpa/inet.h> #include <dlfcn.h> @@ -43,20 +55,31 @@ #include <sys/resource.h> #include <sys/ioctl.h> #include <sys/statvfs.h> -#include <sys/sysinfo.h> #include <sys/utsname.h> #include <sys/mman.h> -#include <sys/vfs.h> #include <dirent.h> #include <pwd.h> #include <sys/socket.h> #include <netdb.h> #include <wordexp.h> -#include <mntent.h> -#include <netinet/ether.h> #include <sys/ipc.h> #include <sys/shm.h> +#if !defined(__FreeBSD__) +# include <malloc.h> +# include <sys/sysinfo.h> +# include <sys/vfs.h> +# include <mntent.h> +# include <netinet/ether.h> +#else +# include <netinet/in.h> +# include <pthread_np.h> +# include <sys/uio.h> +# include <sys/mount.h> +# define f_namelen f_namemax // FreeBSD names this statfs field so. +# define cpu_set_t cpuset_t +#endif + #if defined(__i386__) || defined(__x86_64__) # include <emmintrin.h> # define MSAN_HAS_M128 1 @@ -68,6 +91,19 @@ # include <immintrin.h> #endif +// On FreeBSD procfs is not enabled by default. +#if defined(__FreeBSD__) +# define FILE_TO_READ "/bin/cat" +# define DIR_TO_READ "/bin" +# define SUBFILE_TO_READ "cat" +# define SYMLINK_TO_READ "/usr/bin/tar" +#else +# define FILE_TO_READ "/proc/self/stat" +# define DIR_TO_READ "/proc/self" +# define SUBFILE_TO_READ "stat" +# define SYMLINK_TO_READ "/proc/self/exe" +#endif + static const size_t kPageSize = 4096; typedef unsigned char U1; @@ -493,10 +529,9 @@ static char *DynRetTestStr; TEST(MemorySanitizer, DynRet) { ReturnPoisoned<S8>(); - EXPECT_NOT_POISONED(clearenv()); + EXPECT_NOT_POISONED(atoi("0")); } - TEST(MemorySanitizer, DynRet1) { ReturnPoisoned<S8>(); } @@ -551,7 +586,7 @@ TEST(MemorySanitizer, strerror) { TEST(MemorySanitizer, strerror_r) { errno = 0; char buf[1000]; - char *res = strerror_r(EINVAL, buf, sizeof(buf)); + char *res = (char*) (size_t) strerror_r(EINVAL, buf, sizeof(buf)); ASSERT_EQ(0, errno); if (!res) res = buf; // POSIX version success. EXPECT_NOT_POISONED(strlen(res)); @@ -559,7 +594,7 @@ TEST(MemorySanitizer, strerror_r) { TEST(MemorySanitizer, fread) { char *x = new char[32]; - FILE *f = fopen("/proc/self/stat", "r"); + FILE *f = fopen(FILE_TO_READ, "r"); ASSERT_TRUE(f != NULL); fread(x, 1, 32, f); EXPECT_NOT_POISONED(x[0]); @@ -571,7 +606,7 @@ TEST(MemorySanitizer, fread) { TEST(MemorySanitizer, read) { char *x = new char[32]; - int fd = open("/proc/self/stat", O_RDONLY); + int fd = open(FILE_TO_READ, O_RDONLY); ASSERT_GT(fd, 0); int sz = read(fd, x, 32); ASSERT_EQ(sz, 32); @@ -584,7 +619,7 @@ TEST(MemorySanitizer, read) { TEST(MemorySanitizer, pread) { char *x = new char[32]; - int fd = open("/proc/self/stat", O_RDONLY); + int fd = open(FILE_TO_READ, O_RDONLY); ASSERT_GT(fd, 0); int sz = pread(fd, x, 32, 0); ASSERT_EQ(sz, 32); @@ -602,11 +637,11 @@ TEST(MemorySanitizer, readv) { iov[0].iov_len = 5; iov[1].iov_base = buf + 10; iov[1].iov_len = 2000; - int fd = open("/proc/self/stat", O_RDONLY); + int fd = open(FILE_TO_READ, O_RDONLY); ASSERT_GT(fd, 0); int sz = readv(fd, iov, 2); ASSERT_GE(sz, 0); - ASSERT_LT(sz, 5 + 2000); + ASSERT_LE(sz, 5 + 2000); ASSERT_GT((size_t)sz, iov[0].iov_len); EXPECT_POISONED(buf[0]); EXPECT_NOT_POISONED(buf[1]); @@ -626,11 +661,11 @@ TEST(MemorySanitizer, preadv) { iov[0].iov_len = 5; iov[1].iov_base = buf + 10; iov[1].iov_len = 2000; - int fd = open("/proc/self/stat", O_RDONLY); + int fd = open(FILE_TO_READ, O_RDONLY); ASSERT_GT(fd, 0); int sz = preadv(fd, iov, 2, 3); ASSERT_GE(sz, 0); - ASSERT_LT(sz, 5 + 2000); + ASSERT_LE(sz, 5 + 2000); ASSERT_GT((size_t)sz, iov[0].iov_len); EXPECT_POISONED(buf[0]); EXPECT_NOT_POISONED(buf[1]); @@ -652,15 +687,14 @@ TEST(MemorySanitizer, DISABLED_ioctl) { TEST(MemorySanitizer, readlink) { char *x = new char[1000]; - readlink("/proc/self/exe", x, 1000); + readlink(SYMLINK_TO_READ, x, 1000); EXPECT_NOT_POISONED(x[0]); delete [] x; } - TEST(MemorySanitizer, stat) { struct stat* st = new struct stat; - int res = stat("/proc/self/stat", st); + int res = stat(FILE_TO_READ, st); ASSERT_EQ(0, res); EXPECT_NOT_POISONED(st->st_dev); EXPECT_NOT_POISONED(st->st_mode); @@ -669,9 +703,9 @@ TEST(MemorySanitizer, stat) { TEST(MemorySanitizer, fstatat) { struct stat* st = new struct stat; - int dirfd = open("/proc/self", O_RDONLY); + int dirfd = open(DIR_TO_READ, O_RDONLY); ASSERT_GT(dirfd, 0); - int res = fstatat(dirfd, "stat", st, 0); + int res = fstatat(dirfd, SUBFILE_TO_READ, st, 0); ASSERT_EQ(0, res); EXPECT_NOT_POISONED(st->st_dev); EXPECT_NOT_POISONED(st->st_mode); @@ -763,6 +797,8 @@ TEST(MemorySanitizer, poll) { close(pipefd[1]); } +// There is no ppoll() on FreeBSD. +#if !defined (__FreeBSD__) TEST(MemorySanitizer, ppoll) { int* pipefd = new int[2]; int res = pipe(pipefd); @@ -787,6 +823,7 @@ TEST(MemorySanitizer, ppoll) { close(pipefd[0]); close(pipefd[1]); } +#endif TEST(MemorySanitizer, poll_positive) { int* pipefd = new int[2]; @@ -851,8 +888,11 @@ TEST(MemorySanitizer, accept) { res = fcntl(connect_socket, F_SETFL, O_NONBLOCK); ASSERT_EQ(0, res); res = connect(connect_socket, (struct sockaddr *)&sai, sizeof(sai)); - ASSERT_EQ(-1, res); - ASSERT_EQ(EINPROGRESS, errno); + // On FreeBSD this connection completes immediately. + if (res != 0) { + ASSERT_EQ(-1, res); + ASSERT_EQ(EINPROGRESS, errno); + } __msan_poison(&sai, sizeof(sai)); int new_sock = accept(listen_socket, (struct sockaddr *)&sai, &sz); @@ -973,7 +1013,6 @@ TEST(MemorySanitizer, recvmsg) { ASSERT_EQ(0, res); ASSERT_EQ(sizeof(client_sai), sz); - const char *s = "message text"; struct iovec iov; iov.iov_base = (void *)s; @@ -1125,12 +1164,15 @@ TEST(MemorySanitizer, getcwd_gnu) { free(res); } +// There's no get_current_dir_name() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, get_current_dir_name) { char* res = get_current_dir_name(); ASSERT_TRUE(res != NULL); EXPECT_NOT_POISONED(res[0]); free(res); } +#endif TEST(MemorySanitizer, shmctl) { int id = shmget(IPC_PRIVATE, 4096, 0644 | IPC_CREAT); @@ -1141,6 +1183,8 @@ TEST(MemorySanitizer, shmctl) { ASSERT_GT(res, -1); EXPECT_NOT_POISONED(ds); + // FreeBSD does not support shmctl(IPC_INFO) and shmctl(SHM_INFO). +#if !defined(__FreeBSD__) struct shminfo si; res = shmctl(id, IPC_INFO, (struct shmid_ds *)&si); ASSERT_GT(res, -1); @@ -1150,6 +1194,7 @@ TEST(MemorySanitizer, shmctl) { res = shmctl(id, SHM_INFO, (struct shmid_ds *)&s_i); ASSERT_GT(res, -1); EXPECT_NOT_POISONED(s_i); +#endif res = shmctl(id, IPC_RMID, 0); ASSERT_GT(res, -1); @@ -1157,7 +1202,7 @@ TEST(MemorySanitizer, shmctl) { TEST(MemorySanitizer, shmat) { void *p = mmap(NULL, 4096, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_NE(MAP_FAILED, p); ((char *)p)[10] = *GetPoisoned<U1>(); @@ -1183,6 +1228,8 @@ TEST(MemorySanitizer, shmat) { ASSERT_GT(res, -1); } +// There's no random_r() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, random_r) { int32_t x; char z[64]; @@ -1198,6 +1245,7 @@ TEST(MemorySanitizer, random_r) { ASSERT_EQ(0, res); EXPECT_NOT_POISONED(x); } +#endif TEST(MemorySanitizer, confstr) { char buf[3]; @@ -1215,6 +1263,16 @@ TEST(MemorySanitizer, confstr) { 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); @@ -1251,6 +1309,8 @@ TEST(MemorySanitizer, realpath_null) { free(res); } +// There's no canonicalize_file_name() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, canonicalize_file_name) { const char* relpath = "."; char* res = canonicalize_file_name(relpath); @@ -1258,6 +1318,7 @@ TEST(MemorySanitizer, canonicalize_file_name) { EXPECT_NOT_POISONED(res[0]); free(res); } +#endif extern char **environ; @@ -1655,26 +1716,35 @@ TEST(MemorySanitizer, modfl) { EXPECT_NOT_POISONED(y); } +// There's no sincos() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, sincos) { double s, c; sincos(0.2, &s, &c); EXPECT_NOT_POISONED(s); EXPECT_NOT_POISONED(c); } +#endif +// There's no sincosf() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, sincosf) { float s, c; sincosf(0.2, &s, &c); EXPECT_NOT_POISONED(s); EXPECT_NOT_POISONED(c); } +#endif +// There's no sincosl() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, sincosl) { long double s, c; sincosl(0.2, &s, &c); EXPECT_NOT_POISONED(s); EXPECT_NOT_POISONED(c); } +#endif TEST(MemorySanitizer, remquo) { int quo; @@ -1729,13 +1799,18 @@ TEST(MemorySanitizer, lgammaf_r) { EXPECT_NOT_POISONED(sgn); } +// There's no lgammal_r() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, lgammal_r) { int sgn; long double res = lgammal_r(1.1, &sgn); ASSERT_NE(0.0, res); EXPECT_NOT_POISONED(sgn); } +#endif +// There's no drand48_r() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, drand48_r) { struct drand48_data buf; srand48_r(0, &buf); @@ -1743,7 +1818,10 @@ TEST(MemorySanitizer, drand48_r) { drand48_r(&buf, &d); EXPECT_NOT_POISONED(d); } +#endif +// There's no lrand48_r() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, lrand48_r) { struct drand48_data buf; srand48_r(0, &buf); @@ -1751,6 +1829,7 @@ TEST(MemorySanitizer, lrand48_r) { lrand48_r(&buf, &d); EXPECT_NOT_POISONED(d); } +#endif TEST(MemorySanitizer, sprintf) { // NOLINT char buff[10]; @@ -2015,6 +2094,8 @@ TEST(MemorySanitizer, localtime_r) { EXPECT_NE(0U, strlen(time.tm_zone)); } +// There's no getmntent() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, getmntent) { FILE *fp = setmntent("/etc/fstab", "r"); struct mntent *mnt = getmntent(fp); @@ -2027,7 +2108,10 @@ TEST(MemorySanitizer, getmntent) { EXPECT_NOT_POISONED(mnt->mnt_passno); fclose(fp); } +#endif +// There's no getmntent_r() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, getmntent_r) { FILE *fp = setmntent("/etc/fstab", "r"); struct mntent mntbuf; @@ -2042,6 +2126,7 @@ TEST(MemorySanitizer, getmntent_r) { EXPECT_NOT_POISONED(mnt->mnt_passno); fclose(fp); } +#endif TEST(MemorySanitizer, ether) { const char *asc = "11:22:33:44:55:66"; @@ -2813,12 +2898,15 @@ TEST(MemorySanitizer, dlopenFailed) { #endif // MSAN_TEST_DISABLE_DLOPEN +// There's no sched_getaffinity() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, sched_getaffinity) { cpu_set_t mask; int res = sched_getaffinity(getpid(), sizeof(mask), &mask); ASSERT_EQ(0, res); EXPECT_NOT_POISONED(mask); } +#endif TEST(MemorySanitizer, scanf) { const char *input = "42 hello"; @@ -3048,11 +3136,14 @@ TEST(MemorySanitizer, posix_memalign) { free(p); } +// There's no memalign() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, memalign) { void *p = memalign(4096, 13); EXPECT_EQ(0U, (uintptr_t)p % kPageSize); free(p); } +#endif TEST(MemorySanitizer, valloc) { void *a = valloc(100); @@ -3060,6 +3151,8 @@ TEST(MemorySanitizer, valloc) { free(a); } +// There's no pvalloc() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, pvalloc) { void *p = pvalloc(kPageSize + 100); EXPECT_EQ(0U, (uintptr_t)p % kPageSize); @@ -3071,6 +3164,7 @@ TEST(MemorySanitizer, pvalloc) { EXPECT_EQ(kPageSize, __sanitizer_get_allocated_size(p)); free(p); } +#endif TEST(MemorySanitizer, inet_pton) { const char *s = "1:0:0:0:0:0:0:8"; @@ -3114,12 +3208,15 @@ TEST(MemorySanitizer, gethostname) { EXPECT_NOT_POISONED(strlen(buf)); } +// There's no sysinfo() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, sysinfo) { struct sysinfo info; int res = sysinfo(&info); ASSERT_EQ(0, res); EXPECT_NOT_POISONED(info); } +#endif TEST(MemorySanitizer, getpwuid) { struct passwd *p = getpwuid(0); // root @@ -3207,6 +3304,8 @@ TEST(MemorySanitizer, getpwent_r) { EXPECT_NOT_POISONED(pwdres); } +// There's no fgetpwent() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, fgetpwent) { FILE *fp = fopen("/etc/passwd", "r"); struct passwd *p = fgetpwent(fp); @@ -3217,6 +3316,7 @@ TEST(MemorySanitizer, fgetpwent) { EXPECT_NOT_POISONED(p->pw_uid); fclose(fp); } +#endif TEST(MemorySanitizer, getgrent) { setgrent(); @@ -3228,6 +3328,8 @@ TEST(MemorySanitizer, getgrent) { EXPECT_NOT_POISONED(p->gr_gid); } +// There's no fgetgrent() on FreeBSD. +#if !defined(__FreeBSD__) TEST(MemorySanitizer, fgetgrent) { FILE *fp = fopen("/etc/group", "r"); struct group *grp = fgetgrent(fp); @@ -3242,6 +3344,7 @@ TEST(MemorySanitizer, fgetgrent) { } fclose(fp); } +#endif TEST(MemorySanitizer, getgrent_r) { struct group grp; @@ -3597,7 +3700,7 @@ TEST(MemorySanitizer, UnalignedStore64_precise2) { EXPECT_POISONED_O(x[11], originx3); } -#if defined(__clang__) +#if (defined(__x86_64__) && defined(__clang__)) namespace { typedef U1 V16x8 __attribute__((__vector_size__(16))); typedef U2 V8x16 __attribute__((__vector_size__(16))); @@ -4116,7 +4219,8 @@ TEST(MemorySanitizer, LargeAllocatorUnpoisonsOnFree) { // Allocate the page that was released to the OS in free() with the real mmap, // bypassing the interceptor. - char *q = (char *)real_mmap(p, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + char *q = (char *)real_mmap(p, 4096, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_NE((char *)0, q); ASSERT_TRUE(q <= p); |