msan_test.cc revision e03345ba3da0450f7ff1410de6a2a00fd304089d
1//===-- msan_test.cc ------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of MemorySanitizer. 11// 12// MemorySanitizer unit tests. 13//===----------------------------------------------------------------------===// 14 15#include "sanitizer/msan_interface.h" 16#include "msandr_test_so.h" 17#include "gtest/gtest.h" 18 19#include <stdlib.h> 20#include <stdarg.h> 21#include <stdio.h> 22#include <assert.h> 23#include <wchar.h> 24 25#include <dlfcn.h> 26#include <unistd.h> 27#include <limits.h> 28#include <sys/time.h> 29#include <sys/types.h> 30#include <sys/stat.h> 31#include <fcntl.h> 32#include <sys/resource.h> 33#include <sys/ioctl.h> 34#include <sys/utsname.h> 35#include <sys/mman.h> 36#include <sys/vfs.h> 37 38#if defined(__i386__) || defined(__x86_64__) 39# include <emmintrin.h> 40# define MSAN_HAS_M128 1 41#else 42# define MSAN_HAS_M128 0 43#endif 44 45typedef unsigned char U1; 46typedef unsigned short U2; // NOLINT 47typedef unsigned int U4; 48typedef unsigned long long U8; // NOLINT 49typedef signed char S1; 50typedef signed short S2; // NOLINT 51typedef signed int S4; 52typedef signed long long S8; // NOLINT 53#define NOINLINE __attribute__((noinline)) 54#define INLINE __attribute__((always_inline)) 55 56 57#define EXPECT_POISONED(action) \ 58 do { \ 59 __msan_set_expect_umr(1); \ 60 action; \ 61 __msan_set_expect_umr(0); \ 62 } while (0) 63 64#define EXPECT_POISONED_O(action, origin) \ 65 do { \ 66 __msan_set_expect_umr(1); \ 67 action; \ 68 __msan_set_expect_umr(0); \ 69 if (TrackingOrigins()) \ 70 EXPECT_EQ(origin, __msan_get_origin_tls()); \ 71 } while (0) 72 73#define EXPECT_POISONED_S(action, stack_origin) \ 74 do { \ 75 __msan_set_expect_umr(1); \ 76 action; \ 77 __msan_set_expect_umr(0); \ 78 u32 id = __msan_get_origin_tls(); \ 79 const char *str = __msan_get_origin_descr_if_stack(id); \ 80 if (!str || strcmp(str, stack_origin)) { \ 81 fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s", \ 82 id, stack_origin, str); \ 83 EXPECT_EQ(1, 0); \ 84 } \ 85 } while (0) 86 87 88static U8 poisoned_array[100]; 89template<class T> 90T *GetPoisoned(int i = 0, T val = 0) { 91 T *res = (T*)&poisoned_array[i]; 92 *res = val; 93 __msan_poison(&poisoned_array[i], sizeof(T)); 94 return res; 95} 96 97template<class T> 98T *GetPoisonedO(int i, u32 origin, T val = 0) { 99 T *res = (T*)&poisoned_array[i]; 100 *res = val; 101 __msan_poison(&poisoned_array[i], sizeof(T)); 102 __msan_set_origin(&poisoned_array[i], sizeof(T), origin); 103 return res; 104} 105 106// This function returns its parameter but in such a way that compiler 107// can not prove it. 108template<class T> 109NOINLINE 110static T Ident(T t) { 111 volatile T ret = t; 112 return ret; 113} 114 115static bool TrackingOrigins() { 116 S8 x; 117 __msan_set_origin(&x, sizeof(x), 0x1234); 118 u32 origin = __msan_get_origin(&x); 119 __msan_set_origin(&x, sizeof(x), 0); 120 return origin == 0x1234; 121} 122 123template<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); } 124 125static volatile S1 v_s1; 126static volatile S2 v_s2; 127static volatile S4 v_s4; 128static volatile S8 v_s8; 129static volatile U1 v_u1; 130static volatile U2 v_u2; 131static volatile U4 v_u4; 132static volatile U8 v_u8; 133static void* volatile v_p; 134static volatile double v_d; 135static volatile int g_one = 1; 136static volatile int g_zero = 0; 137static volatile int g_0 = 0; 138static volatile int g_1 = 1; 139 140#if MSAN_HAS_M128 141static volatile __m128i v_m128; 142#endif 143 144S4 a_s4[100]; 145S8 a_s8[100]; 146 147TEST(MemorySanitizer, NegativeTest1) { 148 S4 *x = GetPoisoned<S4>(); 149 if (g_one) 150 *x = 0; 151 v_s4 = *x; 152} 153 154TEST(MemorySanitizer, PositiveTest1) { 155 // Load to store. 156 EXPECT_POISONED(v_s1 = *GetPoisoned<S1>()); 157 EXPECT_POISONED(v_s2 = *GetPoisoned<S2>()); 158 EXPECT_POISONED(v_s4 = *GetPoisoned<S4>()); 159 EXPECT_POISONED(v_s8 = *GetPoisoned<S8>()); 160 161 // S->S conversions. 162 EXPECT_POISONED(v_s2 = *GetPoisoned<S1>()); 163 EXPECT_POISONED(v_s4 = *GetPoisoned<S1>()); 164 EXPECT_POISONED(v_s8 = *GetPoisoned<S1>()); 165 166 EXPECT_POISONED(v_s1 = *GetPoisoned<S2>()); 167 EXPECT_POISONED(v_s4 = *GetPoisoned<S2>()); 168 EXPECT_POISONED(v_s8 = *GetPoisoned<S2>()); 169 170 EXPECT_POISONED(v_s1 = *GetPoisoned<S4>()); 171 EXPECT_POISONED(v_s2 = *GetPoisoned<S4>()); 172 EXPECT_POISONED(v_s8 = *GetPoisoned<S4>()); 173 174 EXPECT_POISONED(v_s1 = *GetPoisoned<S8>()); 175 EXPECT_POISONED(v_s2 = *GetPoisoned<S8>()); 176 EXPECT_POISONED(v_s4 = *GetPoisoned<S8>()); 177 178 // ZExt 179 EXPECT_POISONED(v_s2 = *GetPoisoned<U1>()); 180 EXPECT_POISONED(v_s4 = *GetPoisoned<U1>()); 181 EXPECT_POISONED(v_s8 = *GetPoisoned<U1>()); 182 EXPECT_POISONED(v_s4 = *GetPoisoned<U2>()); 183 EXPECT_POISONED(v_s8 = *GetPoisoned<U2>()); 184 EXPECT_POISONED(v_s8 = *GetPoisoned<U4>()); 185 186 // Unary ops. 187 EXPECT_POISONED(v_s4 = - *GetPoisoned<S4>()); 188 189 EXPECT_POISONED(a_s4[g_zero] = 100 / *GetPoisoned<S4>(0, 1)); 190 191 192 a_s4[g_zero] = 1 - *GetPoisoned<S4>(); 193 a_s4[g_zero] = 1 + *GetPoisoned<S4>(); 194} 195 196TEST(MemorySanitizer, Phi1) { 197 S4 c; 198 if (g_one) { 199 c = *GetPoisoned<S4>(); 200 } else { 201 __msan_break_optimization(0); 202 c = 0; 203 } 204 EXPECT_POISONED(v_s4 = c); 205} 206 207TEST(MemorySanitizer, Phi2) { 208 S4 i = *GetPoisoned<S4>(); 209 S4 n = g_one; 210 EXPECT_POISONED(for (; i < g_one; i++);); 211 EXPECT_POISONED(v_s4 = i); 212} 213 214NOINLINE void Arg1ExpectUMR(S4 a1) { EXPECT_POISONED(v_s4 = a1); } 215NOINLINE void Arg2ExpectUMR(S4 a1, S4 a2) { EXPECT_POISONED(v_s4 = a2); } 216NOINLINE void Arg3ExpectUMR(S1 a1, S4 a2, S8 a3) { EXPECT_POISONED(v_s8 = a3); } 217 218TEST(MemorySanitizer, ArgTest) { 219 Arg1ExpectUMR(*GetPoisoned<S4>()); 220 Arg2ExpectUMR(0, *GetPoisoned<S4>()); 221 Arg3ExpectUMR(0, 1, *GetPoisoned<S8>()); 222} 223 224 225TEST(MemorySanitizer, CallAndRet) { 226 if (!__msan_has_dynamic_component()) return; 227 ReturnPoisoned<S1>(); 228 ReturnPoisoned<S2>(); 229 ReturnPoisoned<S4>(); 230 ReturnPoisoned<S8>(); 231 232 EXPECT_POISONED(v_s1 = ReturnPoisoned<S1>()); 233 EXPECT_POISONED(v_s2 = ReturnPoisoned<S2>()); 234 EXPECT_POISONED(v_s4 = ReturnPoisoned<S4>()); 235 EXPECT_POISONED(v_s8 = ReturnPoisoned<S8>()); 236} 237 238// malloc() in the following test may be optimized to produce a compile-time 239// undef value. Check that we trap on the volatile assignment anyway. 240TEST(MemorySanitizer, DISABLED_MallocNoIdent) { 241 S4 *x = (int*)malloc(sizeof(S4)); 242 EXPECT_POISONED(v_s4 = *x); 243 free(x); 244} 245 246TEST(MemorySanitizer, Malloc) { 247 S4 *x = (int*)Ident(malloc(sizeof(S4))); 248 EXPECT_POISONED(v_s4 = *x); 249 free(x); 250} 251 252TEST(MemorySanitizer, Realloc) { 253 S4 *x = (int*)Ident(realloc(0, sizeof(S4))); 254 EXPECT_POISONED(v_s4 = x[0]); 255 x[0] = 1; 256 x = (int*)Ident(realloc(x, 2 * sizeof(S4))); 257 v_s4 = x[0]; // Ok, was inited before. 258 EXPECT_POISONED(v_s4 = x[1]); 259 x = (int*)Ident(realloc(x, 3 * sizeof(S4))); 260 v_s4 = x[0]; // Ok, was inited before. 261 EXPECT_POISONED(v_s4 = x[2]); 262 EXPECT_POISONED(v_s4 = x[1]); 263 x[2] = 1; // Init this here. Check that after realloc it is poisoned again. 264 x = (int*)Ident(realloc(x, 2 * sizeof(S4))); 265 v_s4 = x[0]; // Ok, was inited before. 266 EXPECT_POISONED(v_s4 = x[1]); 267 x = (int*)Ident(realloc(x, 3 * sizeof(S4))); 268 EXPECT_POISONED(v_s4 = x[1]); 269 EXPECT_POISONED(v_s4 = x[2]); 270 free(x); 271} 272 273TEST(MemorySanitizer, Calloc) { 274 S4 *x = (int*)Ident(calloc(1, sizeof(S4))); 275 v_s4 = *x; // Should not be poisoned. 276 // EXPECT_EQ(0, *x); 277 free(x); 278} 279 280TEST(MemorySanitizer, AndOr) { 281 U4 *p = GetPoisoned<U4>(); 282 // We poison two bytes in the midle of a 4-byte word to make the test 283 // correct regardless of endianness. 284 ((U1*)p)[1] = 0; 285 ((U1*)p)[2] = 0xff; 286 v_u4 = *p & 0x00ffff00; 287 v_u4 = *p & 0x00ff0000; 288 v_u4 = *p & 0x0000ff00; 289 EXPECT_POISONED(v_u4 = *p & 0xff000000); 290 EXPECT_POISONED(v_u4 = *p & 0x000000ff); 291 EXPECT_POISONED(v_u4 = *p & 0x0000ffff); 292 EXPECT_POISONED(v_u4 = *p & 0xffff0000); 293 294 v_u4 = *p | 0xff0000ff; 295 v_u4 = *p | 0xff00ffff; 296 v_u4 = *p | 0xffff00ff; 297 EXPECT_POISONED(v_u4 = *p | 0xff000000); 298 EXPECT_POISONED(v_u4 = *p | 0x000000ff); 299 EXPECT_POISONED(v_u4 = *p | 0x0000ffff); 300 EXPECT_POISONED(v_u4 = *p | 0xffff0000); 301 302 EXPECT_POISONED(v_u4 = *GetPoisoned<bool>() & *GetPoisoned<bool>()); 303} 304 305template<class T> 306static void testNot(T value, T shadow) { 307 __msan_partial_poison(&value, &shadow, sizeof(T)); 308 volatile bool v_T = !value; 309} 310 311TEST(MemorySanitizer, Not) { 312 testNot<U4>(0x0, 0x0); 313 testNot<U4>(0xFFFFFFFF, 0x0); 314 EXPECT_POISONED(testNot<U4>(0xFFFFFFFF, 0xFFFFFFFF)); 315 testNot<U4>(0xFF000000, 0x0FFFFFFF); 316 testNot<U4>(0xFF000000, 0x00FFFFFF); 317 testNot<U4>(0xFF000000, 0x0000FFFF); 318 testNot<U4>(0xFF000000, 0x00000000); 319 EXPECT_POISONED(testNot<U4>(0xFF000000, 0xFF000000)); 320 testNot<U4>(0xFF800000, 0xFF000000); 321 EXPECT_POISONED(testNot<U4>(0x00008000, 0x00008000)); 322 323 testNot<U1>(0x0, 0x0); 324 testNot<U1>(0xFF, 0xFE); 325 testNot<U1>(0xFF, 0x0); 326 EXPECT_POISONED(testNot<U1>(0xFF, 0xFF)); 327 328 EXPECT_POISONED(testNot<void*>((void*)0xFFFFFF, (void*)(-1))); 329 testNot<void*>((void*)0xFFFFFF, (void*)(-2)); 330} 331 332TEST(MemorySanitizer, Shift) { 333 U4 *up = GetPoisoned<U4>(); 334 ((U1*)up)[0] = 0; 335 ((U1*)up)[3] = 0xff; 336 v_u4 = *up >> 30; 337 v_u4 = *up >> 24; 338 EXPECT_POISONED(v_u4 = *up >> 23); 339 EXPECT_POISONED(v_u4 = *up >> 10); 340 341 v_u4 = *up << 30; 342 v_u4 = *up << 24; 343 EXPECT_POISONED(v_u4 = *up << 23); 344 EXPECT_POISONED(v_u4 = *up << 10); 345 346 S4 *sp = (S4*)up; 347 v_s4 = *sp >> 30; 348 v_s4 = *sp >> 24; 349 EXPECT_POISONED(v_s4 = *sp >> 23); 350 EXPECT_POISONED(v_s4 = *sp >> 10); 351 352 sp = GetPoisoned<S4>(); 353 ((S1*)sp)[1] = 0; 354 ((S1*)sp)[2] = 0; 355 EXPECT_POISONED(v_s4 = *sp >> 31); 356 357 v_s4 = 100; 358 EXPECT_POISONED(v_s4 = v_s4 >> *GetPoisoned<S4>()); 359 v_u4 = 100; 360 EXPECT_POISONED(v_u4 = v_u4 >> *GetPoisoned<S4>()); 361 v_u4 = 100; 362 EXPECT_POISONED(v_u4 = v_u4 << *GetPoisoned<S4>()); 363} 364 365NOINLINE static int GetPoisonedZero() { 366 int *zero = new int; 367 *zero = 0; 368 __msan_poison(zero, sizeof(*zero)); 369 int res = *zero; 370 delete zero; 371 return res; 372} 373 374TEST(MemorySanitizer, LoadFromDirtyAddress) { 375 int *a = new int; 376 *a = 0; 377 EXPECT_POISONED(__msan_break_optimization((void*)(U8)a[GetPoisonedZero()])); 378 delete a; 379} 380 381TEST(MemorySanitizer, StoreToDirtyAddress) { 382 int *a = new int; 383 EXPECT_POISONED(a[GetPoisonedZero()] = 0); 384 __msan_break_optimization(a); 385 delete a; 386} 387 388 389NOINLINE void StackTestFunc() { 390 S4 p4; 391 S4 ok4 = 1; 392 S2 p2; 393 S2 ok2 = 1; 394 S1 p1; 395 S1 ok1 = 1; 396 __msan_break_optimization(&p4); 397 __msan_break_optimization(&ok4); 398 __msan_break_optimization(&p2); 399 __msan_break_optimization(&ok2); 400 __msan_break_optimization(&p1); 401 __msan_break_optimization(&ok1); 402 403 EXPECT_POISONED(v_s4 = p4); 404 EXPECT_POISONED(v_s2 = p2); 405 EXPECT_POISONED(v_s1 = p1); 406 v_s1 = ok1; 407 v_s2 = ok2; 408 v_s4 = ok4; 409} 410 411TEST(MemorySanitizer, StackTest) { 412 StackTestFunc(); 413} 414 415NOINLINE void StackStressFunc() { 416 int foo[10000]; 417 __msan_break_optimization(foo); 418} 419 420TEST(MemorySanitizer, DISABLED_StackStressTest) { 421 for (int i = 0; i < 1000000; i++) 422 StackStressFunc(); 423} 424 425template<class T> 426void TestFloatingPoint() { 427 static volatile T v; 428 static T g[100]; 429 __msan_break_optimization(&g); 430 T *x = GetPoisoned<T>(); 431 T *y = GetPoisoned<T>(1); 432 EXPECT_POISONED(v = *x); 433 EXPECT_POISONED(v_s8 = *x); 434 EXPECT_POISONED(v_s4 = *x); 435 g[0] = *x; 436 g[1] = *x + *y; 437 g[2] = *x - *y; 438 g[3] = *x * *y; 439} 440 441TEST(MemorySanitizer, FloatingPointTest) { 442 TestFloatingPoint<float>(); 443 TestFloatingPoint<double>(); 444} 445 446TEST(MemorySanitizer, DynMem) { 447 S4 x = 0; 448 S4 *y = GetPoisoned<S4>(); 449 memcpy(y, &x, g_one * sizeof(S4)); 450 v_s4 = *y; 451} 452 453static char *DynRetTestStr; 454 455TEST(MemorySanitizer, DynRet) { 456 if (!__msan_has_dynamic_component()) return; 457 ReturnPoisoned<S8>(); 458 v_s4 = clearenv(); 459} 460 461 462TEST(MemorySanitizer, DynRet1) { 463 if (!__msan_has_dynamic_component()) return; 464 ReturnPoisoned<S8>(); 465} 466 467struct LargeStruct { 468 S4 x[10]; 469}; 470 471NOINLINE 472LargeStruct LargeRetTest() { 473 LargeStruct res; 474 res.x[0] = *GetPoisoned<S4>(); 475 res.x[1] = *GetPoisoned<S4>(); 476 res.x[2] = *GetPoisoned<S4>(); 477 res.x[3] = *GetPoisoned<S4>(); 478 res.x[4] = *GetPoisoned<S4>(); 479 res.x[5] = *GetPoisoned<S4>(); 480 res.x[6] = *GetPoisoned<S4>(); 481 res.x[7] = *GetPoisoned<S4>(); 482 res.x[8] = *GetPoisoned<S4>(); 483 res.x[9] = *GetPoisoned<S4>(); 484 return res; 485} 486 487TEST(MemorySanitizer, LargeRet) { 488 LargeStruct a = LargeRetTest(); 489 EXPECT_POISONED(v_s4 = a.x[0]); 490 EXPECT_POISONED(v_s4 = a.x[9]); 491} 492 493TEST(MemorySanitizer, fread) { 494 char *x = new char[32]; 495 FILE *f = fopen("/proc/self/stat", "r"); 496 assert(f); 497 fread(x, 1, 32, f); 498 v_s1 = x[0]; 499 v_s1 = x[16]; 500 v_s1 = x[31]; 501 fclose(f); 502 delete x; 503} 504 505TEST(MemorySanitizer, read) { 506 char *x = new char[32]; 507 int fd = open("/proc/self/stat", O_RDONLY); 508 assert(fd > 0); 509 int sz = read(fd, x, 32); 510 assert(sz == 32); 511 v_s1 = x[0]; 512 v_s1 = x[16]; 513 v_s1 = x[31]; 514 close(fd); 515 delete x; 516} 517 518TEST(MemorySanitizer, pread) { 519 char *x = new char[32]; 520 int fd = open("/proc/self/stat", O_RDONLY); 521 assert(fd > 0); 522 int sz = pread(fd, x, 32, 0); 523 assert(sz == 32); 524 v_s1 = x[0]; 525 v_s1 = x[16]; 526 v_s1 = x[31]; 527 close(fd); 528 delete x; 529} 530 531// FIXME: fails now. 532TEST(MemorySanitizer, DISABLED_ioctl) { 533 struct winsize ws; 534 EXPECT_EQ(ioctl(2, TIOCGWINSZ, &ws), 0); 535 v_s4 = ws.ws_col; 536} 537 538TEST(MemorySanitizer, readlink) { 539 char *x = new char[1000]; 540 readlink("/proc/self/exe", x, 1000); 541 v_s1 = x[0]; 542 delete [] x; 543} 544 545 546TEST(MemorySanitizer, stat) { 547 struct stat* st = new struct stat; 548 int res = stat("/proc/self/stat", st); 549 assert(!res); 550 v_u8 = st->st_dev; 551 v_u8 = st->st_mode; 552 v_u8 = st->st_size; 553} 554 555TEST(MemorySanitizer, statfs) { 556 struct statfs* st = new struct statfs; 557 int res = statfs("/", st); 558 assert(!res); 559 v_u8 = st->f_type; 560 v_u8 = st->f_bfree; 561 v_u8 = st->f_namelen; 562} 563 564TEST(MemorySanitizer, pipe) { 565 int* pipefd = new int[2]; 566 int res = pipe(pipefd); 567 assert(!res); 568 v_u8 = pipefd[0]; 569 v_u8 = pipefd[1]; 570 close(pipefd[0]); 571 close(pipefd[1]); 572} 573 574TEST(MemorySanitizer, getcwd) { 575 char path[PATH_MAX + 1]; 576 char* res = getcwd(path, sizeof(path)); 577 assert(res); 578 v_s1 = path[0]; 579} 580 581TEST(MemorySanitizer, realpath) { 582 const char* relpath = "."; 583 char path[PATH_MAX + 1]; 584 char* res = realpath(relpath, path); 585 assert(res); 586 v_s1 = path[0]; 587} 588 589TEST(MemorySanitizer, memcpy) { 590 char* x = new char[2]; 591 char* y = new char[2]; 592 x[0] = 1; 593 x[1] = *GetPoisoned<char>(); 594 memcpy(y, x, 2); 595 v_s4 = y[0]; 596 EXPECT_POISONED(v_s4 = y[1]); 597} 598 599TEST(MemorySanitizer, memmove) { 600 char* x = new char[2]; 601 char* y = new char[2]; 602 x[0] = 1; 603 x[1] = *GetPoisoned<char>(); 604 memmove(y, x, 2); 605 v_s4 = y[0]; 606 EXPECT_POISONED(v_s4 = y[1]); 607} 608 609TEST(MemorySanitizer, strdup) { 610 char *x = strdup("zzz"); 611 v_s1 = *x; 612 free(x); 613} 614 615template<class T, int size> 616void TestOverlapMemmove() { 617 T *x = new T[size]; 618 assert(size >= 3); 619 x[2] = 0; 620 memmove(x, x + 1, (size - 1) * sizeof(T)); 621 v_s8 = x[1]; 622 if (!__msan_has_dynamic_component()) { 623 // FIXME: under DR we will lose this information 624 // because accesses in memmove will unpoisin the shadow. 625 // We need to use our own memove implementation instead of libc's. 626 EXPECT_POISONED(v_s8 = x[0]); 627 EXPECT_POISONED(v_s8 = x[2]); 628 } 629 delete [] x; 630} 631 632TEST(MemorySanitizer, overlap_memmove) { 633 TestOverlapMemmove<U1, 10>(); 634 TestOverlapMemmove<U1, 1000>(); 635 TestOverlapMemmove<U8, 4>(); 636 TestOverlapMemmove<U8, 1000>(); 637} 638 639TEST(MemorySanitizer, strcpy) { // NOLINT 640 char* x = new char[3]; 641 char* y = new char[3]; 642 x[0] = 'a'; 643 x[1] = *GetPoisoned<char>(1, 1); 644 x[2] = 0; 645 strcpy(y, x); // NOLINT 646 v_s4 = y[0]; 647 EXPECT_POISONED(v_s4 = y[1]); 648 v_s4 = y[2]; 649} 650 651TEST(MemorySanitizer, strncpy) { // NOLINT 652 char* x = new char[3]; 653 char* y = new char[3]; 654 x[0] = 'a'; 655 x[1] = *GetPoisoned<char>(1, 1); 656 x[2] = 0; 657 strncpy(y, x, 2); // NOLINT 658 v_s4 = y[0]; 659 EXPECT_POISONED(v_s4 = y[1]); 660 EXPECT_POISONED(v_s4 = y[2]); 661} 662 663TEST(MemorySanitizer, strtol) { 664 char *e; 665 assert(1 == strtol("1", &e, 10)); 666 v_s8 = (S8) e; 667} 668 669TEST(MemorySanitizer, strtoll) { 670 char *e; 671 assert(1 == strtoll("1", &e, 10)); 672 v_s8 = (S8) e; 673} 674 675TEST(MemorySanitizer, strtoul) { 676 char *e; 677 assert(1 == strtoul("1", &e, 10)); 678 v_s8 = (S8) e; 679} 680 681TEST(MemorySanitizer, strtoull) { 682 char *e; 683 assert(1 == strtoull("1", &e, 10)); 684 v_s8 = (S8) e; 685} 686 687TEST(MemorySanitizer, strtod) { 688 char *e; 689 assert(0 != strtod("1.5", &e)); 690 v_s8 = (S8) e; 691} 692 693TEST(MemorySanitizer, strtof) { 694 char *e; 695 assert(0 != strtof("1.5", &e)); 696 v_s8 = (S8) e; 697} 698 699TEST(MemorySanitizer, strtold) { 700 char *e; 701 assert(0 != strtold("1.5", &e)); 702 v_s8 = (S8) e; 703} 704 705TEST(MemorySanitizer, sprintf) { // NOLINT 706 char buff[10]; 707 __msan_break_optimization(buff); 708 EXPECT_POISONED(v_s1 = buff[0]); 709 int res = sprintf(buff, "%d", 1234567); // NOLINT 710 assert(res == 7); 711 assert(buff[0] == '1'); 712 assert(buff[1] == '2'); 713 assert(buff[2] == '3'); 714 assert(buff[6] == '7'); 715 assert(buff[7] == 0); 716 EXPECT_POISONED(v_s1 = buff[8]); 717} 718 719TEST(MemorySanitizer, snprintf) { 720 char buff[10]; 721 __msan_break_optimization(buff); 722 EXPECT_POISONED(v_s1 = buff[0]); 723 int res = snprintf(buff, sizeof(buff), "%d", 1234567); 724 assert(res == 7); 725 assert(buff[0] == '1'); 726 assert(buff[1] == '2'); 727 assert(buff[2] == '3'); 728 assert(buff[6] == '7'); 729 assert(buff[7] == 0); 730 EXPECT_POISONED(v_s1 = buff[8]); 731} 732 733TEST(MemorySanitizer, swprintf) { 734 wchar_t buff[10]; 735 assert(sizeof(wchar_t) == 4); 736 __msan_break_optimization(buff); 737 EXPECT_POISONED(v_s1 = buff[0]); 738 int res = swprintf(buff, 9, L"%d", 1234567); 739 assert(res == 7); 740 assert(buff[0] == '1'); 741 assert(buff[1] == '2'); 742 assert(buff[2] == '3'); 743 assert(buff[6] == '7'); 744 assert(buff[7] == 0); 745 EXPECT_POISONED(v_s4 = buff[8]); 746} 747 748TEST(MemorySanitizer, wcstombs) { 749 const wchar_t *x = L"abc"; 750 char buff[10]; 751 int res = wcstombs(buff, x, 4); 752 EXPECT_EQ(res, 3); 753 EXPECT_EQ(buff[0], 'a'); 754 EXPECT_EQ(buff[1], 'b'); 755 EXPECT_EQ(buff[2], 'c'); 756} 757 758TEST(MemorySanitizer, gettimeofday) { 759 struct timeval tv; 760 struct timezone tz; 761 __msan_break_optimization(&tv); 762 __msan_break_optimization(&tz); 763 assert(sizeof(tv) == 16); 764 assert(sizeof(tz) == 8); 765 EXPECT_POISONED(v_s8 = tv.tv_sec); 766 EXPECT_POISONED(v_s8 = tv.tv_usec); 767 EXPECT_POISONED(v_s4 = tz.tz_minuteswest); 768 EXPECT_POISONED(v_s4 = tz.tz_dsttime); 769 assert(0 == gettimeofday(&tv, &tz)); 770 v_s8 = tv.tv_sec; 771 v_s8 = tv.tv_usec; 772 v_s4 = tz.tz_minuteswest; 773 v_s4 = tz.tz_dsttime; 774} 775 776TEST(MemorySanitizer, mmap) { 777 const int size = 4096; 778 void *p1, *p2; 779 p1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); 780 __msan_poison(p1, size); 781 munmap(p1, size); 782 for (int i = 0; i < 1000; i++) { 783 p2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); 784 if (p2 == p1) 785 break; 786 else 787 munmap(p2, size); 788 } 789 if (p1 == p2) { 790 v_s1 = *(char*)p2; 791 munmap(p2, size); 792 } 793} 794 795// FIXME: enable and add ecvt. 796// FIXME: check why msandr does nt handle fcvt. 797TEST(MemorySanitizer, fcvt) { 798 int a, b; 799 __msan_break_optimization(&a); 800 __msan_break_optimization(&b); 801 EXPECT_POISONED(v_s4 = a); 802 EXPECT_POISONED(v_s4 = b); 803 char *str = fcvt(12345.6789, 10, &a, &b); 804 v_s4 = a; 805 v_s4 = b; 806} 807 808TEST(MemorySanitizer, LoadUnpoisoned) { 809 S8 s = *GetPoisoned<S8>(); 810 EXPECT_POISONED(v_s8 = s); 811 S8 safe = *GetPoisoned<S8>(); 812 __msan_load_unpoisoned(&s, sizeof(s), &safe); 813 v_s8 = safe; 814} 815 816struct StructWithDtor { 817 ~StructWithDtor(); 818}; 819 820NOINLINE StructWithDtor::~StructWithDtor() { 821 __msan_break_optimization(0); 822} 823 824NOINLINE void ExpectGood(int a) { v_s4 = a; } 825NOINLINE void ExpectPoisoned(int a) { 826 EXPECT_POISONED(v_s4 = a); 827} 828 829TEST(MemorySanitizer, Invoke) { 830 StructWithDtor s; // Will cause the calls to become invokes. 831 ExpectGood(0); 832 ExpectPoisoned(*GetPoisoned<int>()); 833 ExpectGood(0); 834 ExpectPoisoned(*GetPoisoned<int>()); 835 EXPECT_POISONED(v_s4 = ReturnPoisoned<S4>()); 836} 837 838TEST(MemorySanitizer, ptrtoint) { 839 // Test that shadow is propagated through pointer-to-integer conversion. 840 void* p = (void*)0xABCD; 841 __msan_poison(((char*)&p) + 1, sizeof(p)); 842 v_u1 = (((uptr)p) & 0xFF) == 0; 843 844 void* q = (void*)0xABCD; 845 __msan_poison(&q, sizeof(q) - 1); 846 EXPECT_POISONED(v_u1 = (((uptr)q) & 0xFF) == 0); 847} 848 849static void vaargsfn2(int guard, ...) { 850 va_list vl; 851 va_start(vl, guard); 852 v_s4 = va_arg(vl, int); 853 v_s4 = va_arg(vl, int); 854 v_s4 = va_arg(vl, int); 855 EXPECT_POISONED(v_d = va_arg(vl, double)); 856 va_end(vl); 857} 858 859static void vaargsfn(int guard, ...) { 860 va_list vl; 861 va_start(vl, guard); 862 v_s4 = va_arg(vl, int); 863 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 864 // The following call will overwrite __msan_param_tls. 865 // Checks after it test that arg shadow was somehow saved across the call. 866 vaargsfn2(1, 2, 3, 4, *GetPoisoned<double>()); 867 v_s4 = va_arg(vl, int); 868 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 869 va_end(vl); 870} 871 872TEST(MemorySanitizer, VAArgTest) { 873 int* x = GetPoisoned<int>(); 874 int* y = GetPoisoned<int>(4); 875 vaargsfn(1, 13, *x, 42, *y); 876} 877 878static void vaargsfn_many(int guard, ...) { 879 va_list vl; 880 va_start(vl, guard); 881 v_s4 = va_arg(vl, int); 882 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 883 v_s4 = va_arg(vl, int); 884 v_s4 = va_arg(vl, int); 885 v_s4 = va_arg(vl, int); 886 v_s4 = va_arg(vl, int); 887 v_s4 = va_arg(vl, int); 888 v_s4 = va_arg(vl, int); 889 v_s4 = va_arg(vl, int); 890 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 891 va_end(vl); 892} 893 894TEST(MemorySanitizer, VAArgManyTest) { 895 int* x = GetPoisoned<int>(); 896 int* y = GetPoisoned<int>(4); 897 vaargsfn_many(1, 2, *x, 3, 4, 5, 6, 7, 8, 9, *y); 898} 899 900static void vaargsfn_pass2(va_list vl) { 901 v_s4 = va_arg(vl, int); 902 v_s4 = va_arg(vl, int); 903 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 904} 905 906static void vaargsfn_pass(int guard, ...) { 907 va_list vl; 908 va_start(vl, guard); 909 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 910 vaargsfn_pass2(vl); 911 va_end(vl); 912} 913 914TEST(MemorySanitizer, VAArgPass) { 915 int* x = GetPoisoned<int>(); 916 int* y = GetPoisoned<int>(4); 917 vaargsfn_pass(1, *x, 2, 3, *y); 918} 919 920static void vaargsfn_copy2(va_list vl) { 921 v_s4 = va_arg(vl, int); 922 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 923} 924 925static void vaargsfn_copy(int guard, ...) { 926 va_list vl; 927 va_start(vl, guard); 928 v_s4 = va_arg(vl, int); 929 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 930 va_list vl2; 931 va_copy(vl2, vl); 932 vaargsfn_copy2(vl2); 933 v_s4 = va_arg(vl, int); 934 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 935 va_end(vl); 936} 937 938TEST(MemorySanitizer, VAArgCopy) { 939 int* x = GetPoisoned<int>(); 940 int* y = GetPoisoned<int>(4); 941 vaargsfn_copy(1, 2, *x, 3, *y); 942} 943 944static void vaargsfn_ptr(int guard, ...) { 945 va_list vl; 946 va_start(vl, guard); 947 v_p = va_arg(vl, int*); 948 EXPECT_POISONED(v_p = va_arg(vl, int*)); 949 v_p = va_arg(vl, int*); 950 EXPECT_POISONED(v_p = va_arg(vl, double*)); 951 va_end(vl); 952} 953 954TEST(MemorySanitizer, VAArgPtr) { 955 int** x = GetPoisoned<int*>(); 956 double** y = GetPoisoned<double*>(8); 957 int z; 958 vaargsfn_ptr(1, &z, *x, &z, *y); 959} 960 961static void vaargsfn_overflow(int guard, ...) { 962 va_list vl; 963 va_start(vl, guard); 964 v_s4 = va_arg(vl, int); 965 v_s4 = va_arg(vl, int); 966 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 967 v_s4 = va_arg(vl, int); 968 v_s4 = va_arg(vl, int); 969 v_s4 = va_arg(vl, int); 970 971 v_d = va_arg(vl, double); 972 v_d = va_arg(vl, double); 973 v_d = va_arg(vl, double); 974 EXPECT_POISONED(v_d = va_arg(vl, double)); 975 v_d = va_arg(vl, double); 976 EXPECT_POISONED(v_p = va_arg(vl, int*)); 977 v_d = va_arg(vl, double); 978 v_d = va_arg(vl, double); 979 980 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 981 EXPECT_POISONED(v_d = va_arg(vl, double)); 982 EXPECT_POISONED(v_p = va_arg(vl, int*)); 983 984 v_s4 = va_arg(vl, int); 985 v_d = va_arg(vl, double); 986 v_p = va_arg(vl, int*); 987 988 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 989 EXPECT_POISONED(v_d = va_arg(vl, double)); 990 EXPECT_POISONED(v_p = va_arg(vl, int*)); 991 992 va_end(vl); 993} 994 995TEST(MemorySanitizer, VAArgOverflow) { 996 int* x = GetPoisoned<int>(); 997 double* y = GetPoisoned<double>(8); 998 int** p = GetPoisoned<int*>(16); 999 int z; 1000 vaargsfn_overflow(1, 1001 1, 2, *x, 4, 5, 6, 1002 1.1, 2.2, 3.3, *y, 5.5, *p, 7.7, 8.8, 1003 // the following args will overflow for sure 1004 *x, *y, *p, 1005 7, 9.9, &z, 1006 *x, *y, *p); 1007} 1008 1009static void vaargsfn_tlsoverwrite2(int guard, ...) { 1010 va_list vl; 1011 va_start(vl, guard); 1012 v_s4 = va_arg(vl, int); 1013 va_end(vl); 1014} 1015 1016static void vaargsfn_tlsoverwrite(int guard, ...) { 1017 // This call will overwrite TLS contents unless it's backed up somewhere. 1018 vaargsfn_tlsoverwrite2(2, 42); 1019 va_list vl; 1020 va_start(vl, guard); 1021 EXPECT_POISONED(v_s4 = va_arg(vl, int)); 1022 va_end(vl); 1023} 1024 1025TEST(MemorySanitizer, VAArgTLSOverwrite) { 1026 int* x = GetPoisoned<int>(); 1027 vaargsfn_tlsoverwrite(1, *x); 1028} 1029 1030struct StructByVal { 1031 int a, b, c, d, e, f; 1032}; 1033 1034NOINLINE void StructByValTestFunc(struct StructByVal s) { 1035 v_s4 = s.a; 1036 EXPECT_POISONED(v_s4 = s.b); 1037 v_s4 = s.c; 1038 EXPECT_POISONED(v_s4 = s.d); 1039 v_s4 = s.e; 1040 EXPECT_POISONED(v_s4 = s.f); 1041} 1042 1043NOINLINE void StructByValTestFunc1(struct StructByVal s) { 1044 StructByValTestFunc(s); 1045} 1046 1047NOINLINE void StructByValTestFunc2(int z, struct StructByVal s) { 1048 StructByValTestFunc(s); 1049} 1050 1051TEST(MemorySanitizer, StructByVal) { 1052 // Large aggregates are passed as "byval" pointer argument in LLVM. 1053 struct StructByVal s; 1054 s.a = 1; 1055 s.b = *GetPoisoned<int>(); 1056 s.c = 2; 1057 s.d = *GetPoisoned<int>(); 1058 s.e = 3; 1059 s.f = *GetPoisoned<int>(); 1060 StructByValTestFunc(s); 1061 StructByValTestFunc1(s); 1062 StructByValTestFunc2(0, s); 1063} 1064 1065 1066#if MSAN_HAS_M128 1067NOINLINE __m128i m128Eq(__m128i *a, __m128i *b) { return *a == *b; } 1068NOINLINE __m128i m128Lt(__m128i *a, __m128i *b) { return *a < *b; } 1069TEST(MemorySanitizer, m128) { 1070 __m128i a = _mm_set1_epi16(0x1234); 1071 __m128i b = _mm_set1_epi16(0x7890); 1072 v_m128 = m128Eq(&a, &b); 1073 v_m128 = m128Lt(&a, &b); 1074} 1075// FIXME: add more tests for __m128i. 1076#endif // MSAN_HAS_M128 1077 1078// We should not complain when copying this poisoned hole. 1079struct StructWithHole { 1080 U4 a; 1081 // 4-byte hole. 1082 U8 b; 1083}; 1084 1085NOINLINE StructWithHole ReturnStructWithHole() { 1086 StructWithHole res; 1087 __msan_poison(&res, sizeof(res)); 1088 res.a = 1; 1089 res.b = 2; 1090 return res; 1091} 1092 1093TEST(MemorySanitizer, StructWithHole) { 1094 StructWithHole a = ReturnStructWithHole(); 1095 __msan_break_optimization(&a); 1096} 1097 1098template <class T> 1099NOINLINE T ReturnStruct() { 1100 T res; 1101 __msan_poison(&res, sizeof(res)); 1102 res.a = 1; 1103 return res; 1104} 1105 1106template <class T> 1107NOINLINE void TestReturnStruct() { 1108 T s1 = ReturnStruct<T>(); 1109 v_s4 = s1.a; 1110 EXPECT_POISONED(v_s4 = s1.b); 1111} 1112 1113struct SSS1 { 1114 int a, b, c; 1115}; 1116struct SSS2 { 1117 int b, a, c; 1118}; 1119struct SSS3 { 1120 int b, c, a; 1121}; 1122struct SSS4 { 1123 int c, b, a; 1124}; 1125 1126struct SSS5 { 1127 int a; 1128 float b; 1129}; 1130struct SSS6 { 1131 int a; 1132 double b; 1133}; 1134struct SSS7 { 1135 S8 b; 1136 int a; 1137}; 1138struct SSS8 { 1139 S2 b; 1140 S8 a; 1141}; 1142 1143TEST(MemorySanitizer, IntStruct3) { 1144 TestReturnStruct<SSS1>(); 1145 TestReturnStruct<SSS2>(); 1146 TestReturnStruct<SSS3>(); 1147 TestReturnStruct<SSS4>(); 1148 TestReturnStruct<SSS5>(); 1149 TestReturnStruct<SSS6>(); 1150 TestReturnStruct<SSS7>(); 1151 TestReturnStruct<SSS8>(); 1152} 1153 1154struct LongStruct { 1155 U1 a1, b1; 1156 U2 a2, b2; 1157 U4 a4, b4; 1158 U8 a8, b8; 1159}; 1160 1161NOINLINE LongStruct ReturnLongStruct1() { 1162 LongStruct res; 1163 __msan_poison(&res, sizeof(res)); 1164 res.a1 = res.a2 = res.a4 = res.a8 = 111; 1165 // leaves b1, .., b8 poisoned. 1166 return res; 1167} 1168 1169NOINLINE LongStruct ReturnLongStruct2() { 1170 LongStruct res; 1171 __msan_poison(&res, sizeof(res)); 1172 res.b1 = res.b2 = res.b4 = res.b8 = 111; 1173 // leaves a1, .., a8 poisoned. 1174 return res; 1175} 1176 1177TEST(MemorySanitizer, LongStruct) { 1178 LongStruct s1 = ReturnLongStruct1(); 1179 __msan_print_shadow(&s1, sizeof(s1)); 1180 v_u1 = s1.a1; 1181 v_u2 = s1.a2; 1182 v_u4 = s1.a4; 1183 v_u8 = s1.a8; 1184 1185 EXPECT_POISONED(v_u1 = s1.b1); 1186 EXPECT_POISONED(v_u2 = s1.b2); 1187 EXPECT_POISONED(v_u4 = s1.b4); 1188 EXPECT_POISONED(v_u8 = s1.b8); 1189 1190 LongStruct s2 = ReturnLongStruct2(); 1191 __msan_print_shadow(&s2, sizeof(s2)); 1192 v_u1 = s2.b1; 1193 v_u2 = s2.b2; 1194 v_u4 = s2.b4; 1195 v_u8 = s2.b8; 1196 1197 EXPECT_POISONED(v_u1 = s2.a1); 1198 EXPECT_POISONED(v_u2 = s2.a2); 1199 EXPECT_POISONED(v_u4 = s2.a4); 1200 EXPECT_POISONED(v_u8 = s2.a8); 1201} 1202 1203TEST(MemorySanitizer, getrlimit) { 1204 struct rlimit limit; 1205 __msan_poison(&limit, sizeof(limit)); 1206 int result = getrlimit(RLIMIT_DATA, &limit); 1207 assert(result == 0); 1208 volatile rlim_t t; 1209 t = limit.rlim_cur; 1210 t = limit.rlim_max; 1211} 1212 1213TEST(MemorySanitizer, getrusage) { 1214 struct rusage usage; 1215 __msan_poison(&usage, sizeof(usage)); 1216 int result = getrusage(RUSAGE_SELF, &usage); 1217 assert(result == 0); 1218 volatile struct timeval t; 1219 v_u8 = usage.ru_utime.tv_sec; 1220 v_u8 = usage.ru_utime.tv_usec; 1221 v_u8 = usage.ru_stime.tv_sec; 1222 v_u8 = usage.ru_stime.tv_usec; 1223 v_s8 = usage.ru_maxrss; 1224 v_s8 = usage.ru_minflt; 1225 v_s8 = usage.ru_majflt; 1226 v_s8 = usage.ru_inblock; 1227 v_s8 = usage.ru_oublock; 1228 v_s8 = usage.ru_nvcsw; 1229 v_s8 = usage.ru_nivcsw; 1230} 1231 1232static void dladdr_testfn() {} 1233 1234TEST(MemorySanitizer, dladdr) { 1235 Dl_info info; 1236 __msan_poison(&info, sizeof(info)); 1237 int result = dladdr((const void*)dladdr_testfn, &info); 1238 assert(result != 0); 1239 v_u8 = (unsigned long)info.dli_fname; 1240 if (info.dli_fname) 1241 v_u8 = strlen(info.dli_fname); 1242 v_u8 = (unsigned long)info.dli_fbase; 1243 v_u8 = (unsigned long)info.dli_sname; 1244 if (info.dli_sname) 1245 v_u8 = strlen(info.dli_sname); 1246 v_u8 = (unsigned long)info.dli_saddr; 1247} 1248 1249static void* SimpleThread_threadfn(void* data) { 1250 return new int; 1251} 1252 1253TEST(MemorySanitizer, SimpleThread) { 1254 pthread_t t; 1255 void* p; 1256 int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL); 1257 assert(!res); 1258 res = pthread_join(t, &p); 1259 assert(!res); 1260 if (!__msan_has_dynamic_component()) // FIXME: intercept pthread_join (?). 1261 __msan_unpoison(&p, sizeof(p)); 1262 delete (int*)p; 1263} 1264 1265TEST(MemorySanitizer, uname) { 1266 struct utsname u; 1267 int res = uname(&u); 1268 assert(!res); 1269 v_u8 = strlen(u.sysname); 1270 v_u8 = strlen(u.nodename); 1271 v_u8 = strlen(u.release); 1272 v_u8 = strlen(u.version); 1273 v_u8 = strlen(u.machine); 1274} 1275 1276template<class T> 1277static void testSlt(T value, T shadow) { 1278 __msan_partial_poison(&value, &shadow, sizeof(T)); 1279 volatile bool zzz = true; 1280 // This "|| zzz" trick somehow makes LLVM emit "icmp slt" instead of 1281 // a shift-and-trunc to get at the highest bit. 1282 volatile bool v_T = value < 0 || zzz; 1283} 1284 1285TEST(MemorySanitizer, SignedCompareWithZero) { 1286 testSlt<S4>(0xF, 0xF); 1287 testSlt<S4>(0xF, 0xFF); 1288 testSlt<S4>(0xF, 0xFFFFFF); 1289 testSlt<S4>(0xF, 0x7FFFFFF); 1290 EXPECT_POISONED(testSlt<S4>(0xF, 0x80FFFFFF)); 1291 EXPECT_POISONED(testSlt<S4>(0xF, 0xFFFFFFFF)); 1292} 1293 1294extern "C" { 1295NOINLINE void ZZZZZZZZZZZZZZ() { 1296 __msan_break_optimization(0); 1297 1298 // v_s1 = ReturnPoisoned<S1>(); 1299 // a_s8[g_zero] = *GetPoisoned<S8>() - 1; 1300 // v_s4 = a_s4[g_zero]; 1301 __msan_break_optimization(0); 1302} 1303} 1304 1305TEST(MemorySanitizer, ZZZTest) { 1306 ZZZZZZZZZZZZZZ(); 1307} 1308 1309TEST(MemorySanitizerDr, StoreInDSOTest) { 1310 if (!__msan_has_dynamic_component()) return; 1311 char* s = new char[10]; 1312 dso_memfill(s, 9); 1313 v_s1 = s[5]; 1314 EXPECT_POISONED(v_s1 = s[9]); 1315} 1316 1317int return_poisoned_int() { 1318 return ReturnPoisoned<U8>(); 1319} 1320 1321TEST(MemorySanitizerDr, ReturnFromDSOTest) { 1322 if (!__msan_has_dynamic_component()) return; 1323 v_u8 = dso_callfn(return_poisoned_int); 1324} 1325 1326NOINLINE int TrashParamTLS(long long x, long long y, long long z) { //NOLINT 1327 EXPECT_POISONED(v_s8 = x); 1328 EXPECT_POISONED(v_s8 = y); 1329 EXPECT_POISONED(v_s8 = z); 1330 return 0; 1331} 1332 1333static int CheckParamTLS(long long x, long long y, long long z) { //NOLINT 1334 v_s8 = x; 1335 v_s8 = y; 1336 v_s8 = z; 1337 return 0; 1338} 1339 1340TEST(MemorySanitizerDr, CallFromDSOTest) { 1341 if (!__msan_has_dynamic_component()) return; 1342 S8* x = GetPoisoned<S8>(); 1343 S8* y = GetPoisoned<S8>(); 1344 S8* z = GetPoisoned<S8>(); 1345 v_s4 = TrashParamTLS(*x, *y, *z); 1346 v_u8 = dso_callfn1(CheckParamTLS); 1347} 1348 1349static void StackStoreInDSOFn(int* x, int* y) { 1350 v_s4 = *x; 1351 v_s4 = *y; 1352} 1353 1354TEST(MemorySanitizerDr, StackStoreInDSOTest) { 1355 if (!__msan_has_dynamic_component()) return; 1356 dso_stack_store(StackStoreInDSOFn, 1); 1357} 1358 1359TEST(MemorySanitizerOrigins, SetGet) { 1360 EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins()); 1361 if (!TrackingOrigins()) return; 1362 int x; 1363 __msan_set_origin(&x, sizeof(x), 1234); 1364 EXPECT_EQ(1234, __msan_get_origin(&x)); 1365 __msan_set_origin(&x, sizeof(x), 5678); 1366 EXPECT_EQ(5678, __msan_get_origin(&x)); 1367 __msan_set_origin(&x, sizeof(x), 0); 1368 EXPECT_EQ(0, __msan_get_origin(&x)); 1369} 1370 1371namespace { 1372struct S { 1373 U4 dummy; 1374 U2 a; 1375 U2 b; 1376}; 1377 1378// http://code.google.com/p/memory-sanitizer/issues/detail?id=6 1379TEST(MemorySanitizerOrigins, DISABLED_InitializedStoreDoesNotChangeOrigin) { 1380 if (!TrackingOrigins()) return; 1381 1382 S s; 1383 u32 origin = rand(); // NOLINT 1384 s.a = *GetPoisonedO<U2>(0, origin); 1385 EXPECT_EQ(origin, __msan_get_origin(&s.a)); 1386 EXPECT_EQ(origin, __msan_get_origin(&s.b)); 1387 1388 s.b = 42; 1389 EXPECT_EQ(origin, __msan_get_origin(&s.a)); 1390 EXPECT_EQ(origin, __msan_get_origin(&s.b)); 1391} 1392} // namespace 1393 1394template<class T, class BinaryOp> 1395INLINE 1396void BinaryOpOriginTest(BinaryOp op) { 1397 u32 ox = rand(); //NOLINT 1398 u32 oy = rand(); //NOLINT 1399 T *x = GetPoisonedO<T>(0, ox, 0); 1400 T *y = GetPoisonedO<T>(1, oy, 0); 1401 T *z = GetPoisonedO<T>(2, 0, 0); 1402 1403 *z = op(*x, *y); 1404 u32 origin = __msan_get_origin(z); 1405 EXPECT_POISONED_O(v_s8 = *z, origin); 1406 EXPECT_EQ(true, origin == ox || origin == oy); 1407 1408 // y is poisoned, x is not. 1409 *x = 10101; 1410 *y = *GetPoisonedO<T>(1, oy); 1411 __msan_break_optimization(x); 1412 __msan_set_origin(z, sizeof(*z), 0); 1413 *z = op(*x, *y); 1414 EXPECT_POISONED_O(v_s8 = *z, oy); 1415 EXPECT_EQ(__msan_get_origin(z), oy); 1416 1417 // x is poisoned, y is not. 1418 *x = *GetPoisonedO<T>(0, ox); 1419 *y = 10101010; 1420 __msan_break_optimization(y); 1421 __msan_set_origin(z, sizeof(*z), 0); 1422 *z = op(*x, *y); 1423 EXPECT_POISONED_O(v_s8 = *z, ox); 1424 EXPECT_EQ(__msan_get_origin(z), ox); 1425} 1426 1427template<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; } 1428template<class T> INLINE T ADD(const T &a, const T&b) { return a + b; } 1429template<class T> INLINE T SUB(const T &a, const T&b) { return a - b; } 1430template<class T> INLINE T MUL(const T &a, const T&b) { return a * b; } 1431template<class T> INLINE T AND(const T &a, const T&b) { return a & b; } 1432template<class T> INLINE T OR (const T &a, const T&b) { return a | b; } 1433 1434TEST(MemorySanitizerOrigins, BinaryOp) { 1435 if (!TrackingOrigins()) return; 1436 BinaryOpOriginTest<S8>(XOR<S8>); 1437 BinaryOpOriginTest<U8>(ADD<U8>); 1438 BinaryOpOriginTest<S4>(SUB<S4>); 1439 BinaryOpOriginTest<S4>(MUL<S4>); 1440 BinaryOpOriginTest<U4>(OR<U4>); 1441 BinaryOpOriginTest<U4>(AND<U4>); 1442 BinaryOpOriginTest<double>(ADD<U4>); 1443 BinaryOpOriginTest<float>(ADD<S4>); 1444 BinaryOpOriginTest<double>(ADD<double>); 1445 BinaryOpOriginTest<float>(ADD<double>); 1446} 1447 1448TEST(MemorySanitizerOrigins, Unary) { 1449 if (!TrackingOrigins()) return; 1450 EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S8>(0, __LINE__), __LINE__); 1451 EXPECT_POISONED_O(v_s4 = *GetPoisonedO<S8>(0, __LINE__), __LINE__); 1452 EXPECT_POISONED_O(v_s2 = *GetPoisonedO<S8>(0, __LINE__), __LINE__); 1453 EXPECT_POISONED_O(v_s1 = *GetPoisonedO<S8>(0, __LINE__), __LINE__); 1454 1455 EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1456 EXPECT_POISONED_O(v_s4 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1457 EXPECT_POISONED_O(v_s2 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1458 EXPECT_POISONED_O(v_s1 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1459 1460 EXPECT_POISONED_O(v_s8 = *GetPoisonedO<U4>(0, __LINE__), __LINE__); 1461 EXPECT_POISONED_O(v_s4 = *GetPoisonedO<U4>(0, __LINE__), __LINE__); 1462 EXPECT_POISONED_O(v_s2 = *GetPoisonedO<U4>(0, __LINE__), __LINE__); 1463 EXPECT_POISONED_O(v_s1 = *GetPoisonedO<U4>(0, __LINE__), __LINE__); 1464 1465 EXPECT_POISONED_O(v_u8 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1466 EXPECT_POISONED_O(v_u4 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1467 EXPECT_POISONED_O(v_u2 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1468 EXPECT_POISONED_O(v_u1 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1469 1470 EXPECT_POISONED_O(v_p = (void*)*GetPoisonedO<S8>(0, __LINE__), __LINE__); 1471 EXPECT_POISONED_O(v_u8 = (U8)*GetPoisonedO<void*>(0, __LINE__), __LINE__); 1472} 1473 1474TEST(MemorySanitizerOrigins, EQ) { 1475 if (!TrackingOrigins()) return; 1476 EXPECT_POISONED_O(v_u1 = *GetPoisonedO<S4>(0, __LINE__) <= 11, __LINE__); 1477 EXPECT_POISONED_O(v_u1 = *GetPoisonedO<S4>(0, __LINE__) == 11, __LINE__); 1478 EXPECT_POISONED_O(v_u1 = *GetPoisonedO<float>(0, __LINE__) == 1.1, __LINE__); 1479} 1480 1481TEST(MemorySanitizerOrigins, DIV) { 1482 if (!TrackingOrigins()) return; 1483 EXPECT_POISONED_O(v_u8 = *GetPoisonedO<U8>(0, __LINE__) / 100, __LINE__); 1484 EXPECT_POISONED_O(v_s4 = 100 / *GetPoisonedO<S4>(0, __LINE__, 1), __LINE__); 1485} 1486 1487TEST(MemorySanitizerOrigins, SHIFT) { 1488 if (!TrackingOrigins()) return; 1489 EXPECT_POISONED_O(v_u8 = *GetPoisonedO<U8>(0, __LINE__) >> 10, __LINE__); 1490 EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S8>(0, __LINE__) >> 10, __LINE__); 1491 EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S8>(0, __LINE__) << 10, __LINE__); 1492 EXPECT_POISONED_O(v_u8 = 10U << *GetPoisonedO<U8>(0, __LINE__), __LINE__); 1493 EXPECT_POISONED_O(v_s8 = -10 >> *GetPoisonedO<S8>(0, __LINE__), __LINE__); 1494 EXPECT_POISONED_O(v_s8 = -10 << *GetPoisonedO<S8>(0, __LINE__), __LINE__); 1495} 1496 1497template<class T, int N> 1498void MemCpyTest() { 1499 int ox = __LINE__; 1500 T *x = new T[N]; 1501 T *y = new T[N]; 1502 T *z = new T[N]; 1503 __msan_poison(x, N * sizeof(T)); 1504 __msan_set_origin(x, N * sizeof(T), ox); 1505 __msan_set_origin(y, N * sizeof(T), 777777); 1506 __msan_set_origin(z, N * sizeof(T), 888888); 1507 v_p = x; 1508 memcpy(y, v_p, N * sizeof(T)); 1509 EXPECT_POISONED_O(v_s1 = y[0], ox); 1510 EXPECT_POISONED_O(v_s1 = y[N/2], ox); 1511 EXPECT_POISONED_O(v_s1 = y[N-1], ox); 1512 v_p = x; 1513 memmove(z, v_p, N * sizeof(T)); 1514 EXPECT_POISONED_O(v_s1 = z[0], ox); 1515 EXPECT_POISONED_O(v_s1 = z[N/2], ox); 1516 EXPECT_POISONED_O(v_s1 = z[N-1], ox); 1517} 1518 1519TEST(MemorySanitizerOrigins, LargeMemCpy) { 1520 if (!TrackingOrigins()) return; 1521 MemCpyTest<U1, 10000>(); 1522 MemCpyTest<U8, 10000>(); 1523} 1524 1525TEST(MemorySanitizerOrigins, SmallMemCpy) { 1526 if (!TrackingOrigins()) return; 1527 MemCpyTest<U8, 1>(); 1528 MemCpyTest<U8, 2>(); 1529 MemCpyTest<U8, 3>(); 1530} 1531 1532TEST(MemorySanitizerOrigins, Select) { 1533 if (!TrackingOrigins()) return; 1534 v_s8 = g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__); 1535 EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1536 S4 x; 1537 __msan_break_optimization(&x); 1538 x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0; 1539 1540 EXPECT_POISONED_O(v_s8 = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__); 1541 EXPECT_POISONED_O(v_s8 = g_0 ? 1 : *GetPoisonedO<S4>(0, __LINE__), __LINE__); 1542} 1543 1544extern "C" 1545NOINLINE void AllocaTOTest() { 1546 int ar[100]; 1547 __msan_break_optimization(ar); 1548 v_s8 = ar[10]; 1549 // fprintf(stderr, "Descr: %s\n", 1550 // __msan_get_origin_descr_if_stack(__msan_get_origin_tls())); 1551} 1552 1553TEST(MemorySanitizerOrigins, Alloca) { 1554 if (!TrackingOrigins()) return; 1555 EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest"); 1556 EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest"); 1557 EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest"); 1558 EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest"); 1559} 1560 1561// FIXME: replace with a lit-like test. 1562TEST(MemorySanitizerOrigins, DISABLED_AllocaDeath) { 1563 if (!TrackingOrigins()) return; 1564 EXPECT_DEATH(AllocaTOTest(), "ORIGIN: stack allocation: ar@AllocaTOTest"); 1565} 1566 1567NOINLINE int RetvalOriginTest(u32 origin) { 1568 int *a = new int; 1569 __msan_break_optimization(a); 1570 __msan_set_origin(a, sizeof(*a), origin); 1571 int res = *a; 1572 delete a; 1573 return res; 1574} 1575 1576TEST(MemorySanitizerOrigins, Retval) { 1577 if (!TrackingOrigins()) return; 1578 EXPECT_POISONED_O(v_s4 = RetvalOriginTest(__LINE__), __LINE__); 1579} 1580 1581NOINLINE void ParamOriginTest(int param, u32 origin) { 1582 EXPECT_POISONED_O(v_s4 = param, origin); 1583} 1584 1585TEST(MemorySanitizerOrigins, Param) { 1586 if (!TrackingOrigins()) return; 1587 int *a = new int; 1588 u32 origin = __LINE__; 1589 __msan_break_optimization(a); 1590 __msan_set_origin(a, sizeof(*a), origin); 1591 ParamOriginTest(*a, origin); 1592 delete a; 1593} 1594 1595TEST(MemorySanitizerOrigins, Invoke) { 1596 if (!TrackingOrigins()) return; 1597 StructWithDtor s; // Will cause the calls to become invokes. 1598 EXPECT_POISONED_O(v_s4 = RetvalOriginTest(__LINE__), __LINE__); 1599} 1600 1601TEST(MemorySanitizerOrigins, strlen) { 1602 S8 alignment; 1603 __msan_break_optimization(&alignment); 1604 char x[4] = {'a', 'b', 0, 0}; 1605 __msan_poison(&x[2], 1); 1606 u32 origin = __LINE__; 1607 __msan_set_origin(x, sizeof(x), origin); 1608 EXPECT_POISONED_O(v_s4 = strlen(x), origin); 1609} 1610 1611TEST(MemorySanitizerOrigins, wcslen) { 1612 wchar_t w[3] = {'a', 'b', 0}; 1613 u32 origin = __LINE__; 1614 __msan_set_origin(w, sizeof(w), origin); 1615 __msan_poison(&w[2], sizeof(wchar_t)); 1616 EXPECT_POISONED_O(v_s4 = wcslen(w), origin); 1617} 1618 1619#if MSAN_HAS_M128 1620TEST(MemorySanitizerOrigins, StoreIntrinsic) { 1621 __m128 x, y; 1622 u32 origin = __LINE__; 1623 __msan_set_origin(&x, sizeof(x), origin); 1624 __msan_poison(&x, sizeof(x)); 1625 __builtin_ia32_storeups((float*)&y, x); 1626 EXPECT_POISONED_O(v_m128 = y, origin); 1627} 1628#endif 1629 1630NOINLINE void RecursiveMalloc(int depth) { 1631 static int count; 1632 count++; 1633 if ((count % (1024 * 1024)) == 0) 1634 printf("RecursiveMalloc: %d\n", count); 1635 int *x1 = new int; 1636 int *x2 = new int; 1637 __msan_break_optimization(x1); 1638 __msan_break_optimization(x2); 1639 if (depth > 0) { 1640 RecursiveMalloc(depth-1); 1641 RecursiveMalloc(depth-1); 1642 } 1643 delete x1; 1644 delete x2; 1645} 1646 1647TEST(MemorySanitizerStress, DISABLED_MallocStackTrace) { 1648 RecursiveMalloc(22); 1649} 1650 1651int main(int argc, char **argv) { 1652 __msan_set_poison_in_malloc(1); 1653 testing::InitGoogleTest(&argc, argv); 1654 int res = RUN_ALL_TESTS(); 1655 return res; 1656} 1657