blob: e6612baa0f7ef5eb3ea3e1961bbf0bee97d4a7fe [file] [log] [blame]
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001//===-- 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
Evgeniy Stepanov6e5ff892013-03-22 09:01:26 +000015#ifndef MSAN_EXTERNAL_TEST_CONFIG
16#include "msan_test_config.h"
17#endif // MSAN_EXTERNAL_TEST_CONFIG
18
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000019#include "sanitizer/msan_interface.h"
20#include "msandr_test_so.h"
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000021
22#include <stdlib.h>
23#include <stdarg.h>
24#include <stdio.h>
25#include <assert.h>
26#include <wchar.h>
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +000027#include <math.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000028
Evgeniy Stepanove03345b2013-01-17 13:42:17 +000029#include <dlfcn.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000030#include <unistd.h>
31#include <limits.h>
32#include <sys/time.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <fcntl.h>
36#include <sys/resource.h>
37#include <sys/ioctl.h>
38#include <sys/utsname.h>
39#include <sys/mman.h>
40#include <sys/vfs.h>
Evgeniy Stepanovd97a15a2013-03-14 12:49:23 +000041#include <sys/types.h>
42#include <dirent.h>
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +000043#include <pwd.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000044
45#if defined(__i386__) || defined(__x86_64__)
46# include <emmintrin.h>
47# define MSAN_HAS_M128 1
48#else
49# define MSAN_HAS_M128 0
50#endif
51
52typedef unsigned char U1;
53typedef unsigned short U2; // NOLINT
54typedef unsigned int U4;
55typedef unsigned long long U8; // NOLINT
56typedef signed char S1;
57typedef signed short S2; // NOLINT
58typedef signed int S4;
59typedef signed long long S8; // NOLINT
60#define NOINLINE __attribute__((noinline))
61#define INLINE __attribute__((always_inline))
62
Evgeniy Stepanov11929002013-01-22 12:29:00 +000063static bool TrackingOrigins() {
64 S8 x;
65 __msan_set_origin(&x, sizeof(x), 0x1234);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +000066 U4 origin = __msan_get_origin(&x);
Evgeniy Stepanov11929002013-01-22 12:29:00 +000067 __msan_set_origin(&x, sizeof(x), 0);
68 return origin == 0x1234;
69}
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000070
Evgeniy Stepanov11929002013-01-22 12:29:00 +000071#define EXPECT_UMR(action) \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000072 do { \
73 __msan_set_expect_umr(1); \
74 action; \
75 __msan_set_expect_umr(0); \
76 } while (0)
77
Evgeniy Stepanov11929002013-01-22 12:29:00 +000078#define EXPECT_UMR_O(action, origin) \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000079 do { \
80 __msan_set_expect_umr(1); \
81 action; \
82 __msan_set_expect_umr(0); \
83 if (TrackingOrigins()) \
Evgeniy Stepanov12c46932013-01-29 14:33:29 +000084 EXPECT_EQ(origin, __msan_get_umr_origin()); \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000085 } while (0)
86
Evgeniy Stepanov11929002013-01-22 12:29:00 +000087#define EXPECT_UMR_S(action, stack_origin) \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000088 do { \
89 __msan_set_expect_umr(1); \
90 action; \
91 __msan_set_expect_umr(0); \
Evgeniy Stepanov250f2212013-01-30 13:12:08 +000092 U4 id = __msan_get_umr_origin(); \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000093 const char *str = __msan_get_origin_descr_if_stack(id); \
94 if (!str || strcmp(str, stack_origin)) { \
95 fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s", \
96 id, stack_origin, str); \
97 EXPECT_EQ(1, 0); \
98 } \
99 } while (0)
100
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000101#define EXPECT_POISONED(x) ExpectPoisoned(x)
102
103template<typename T>
104void ExpectPoisoned(const T& t) {
105 EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
106}
107
108#define EXPECT_POISONED_O(x, origin) \
109 ExpectPoisonedWithOrigin(x, origin)
110
111template<typename T>
112void ExpectPoisonedWithOrigin(const T& t, unsigned origin) {
113 EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
114 if (TrackingOrigins())
115 EXPECT_EQ(origin, __msan_get_origin((void*)&t));
116}
117
118#define EXPECT_POISONED_S(x, stack_origin) \
119 ExpectPoisonedWithStackOrigin(x, stack_origin)
120
121template<typename T>
122void ExpectPoisonedWithStackOrigin(const T& t, const char *stack_origin) {
123 EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
Evgeniy Stepanov250f2212013-01-30 13:12:08 +0000124 U4 id = __msan_get_origin((void*)&t);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000125 const char *str = __msan_get_origin_descr_if_stack(id);
126 if (!str || strcmp(str, stack_origin)) {
127 fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s",
128 id, stack_origin, str);
129 EXPECT_EQ(1, 0);
130 }
131}
132
133#define EXPECT_NOT_POISONED(x) ExpectNotPoisoned(x)
134
135template<typename T>
136void ExpectNotPoisoned(const T& t) {
137 EXPECT_EQ(-1, __msan_test_shadow((void*)&t, sizeof(t)));
138}
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000139
140static U8 poisoned_array[100];
141template<class T>
142T *GetPoisoned(int i = 0, T val = 0) {
143 T *res = (T*)&poisoned_array[i];
144 *res = val;
145 __msan_poison(&poisoned_array[i], sizeof(T));
146 return res;
147}
148
149template<class T>
Evgeniy Stepanov250f2212013-01-30 13:12:08 +0000150T *GetPoisonedO(int i, U4 origin, T val = 0) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000151 T *res = (T*)&poisoned_array[i];
152 *res = val;
153 __msan_poison(&poisoned_array[i], sizeof(T));
154 __msan_set_origin(&poisoned_array[i], sizeof(T), origin);
155 return res;
156}
157
158// This function returns its parameter but in such a way that compiler
159// can not prove it.
160template<class T>
161NOINLINE
162static T Ident(T t) {
163 volatile T ret = t;
164 return ret;
165}
166
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000167template<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); }
168
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000169static volatile int g_one = 1;
170static volatile int g_zero = 0;
171static volatile int g_0 = 0;
172static volatile int g_1 = 1;
173
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000174S4 a_s4[100];
175S8 a_s8[100];
176
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000177// Check that malloc poisons memory.
178// A lot of tests below depend on this.
179TEST(MemorySanitizerSanity, PoisonInMalloc) {
180 int *x = (int*)malloc(sizeof(int));
181 EXPECT_POISONED(*x);
182 free(x);
183}
184
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000185TEST(MemorySanitizer, NegativeTest1) {
186 S4 *x = GetPoisoned<S4>();
187 if (g_one)
188 *x = 0;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000189 EXPECT_NOT_POISONED(*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000190}
191
192TEST(MemorySanitizer, PositiveTest1) {
193 // Load to store.
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000194 EXPECT_POISONED(*GetPoisoned<S1>());
195 EXPECT_POISONED(*GetPoisoned<S2>());
196 EXPECT_POISONED(*GetPoisoned<S4>());
197 EXPECT_POISONED(*GetPoisoned<S8>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000198
199 // S->S conversions.
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000200 EXPECT_POISONED(*GetPoisoned<S1>());
201 EXPECT_POISONED(*GetPoisoned<S1>());
202 EXPECT_POISONED(*GetPoisoned<S1>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000203
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000204 EXPECT_POISONED(*GetPoisoned<S2>());
205 EXPECT_POISONED(*GetPoisoned<S2>());
206 EXPECT_POISONED(*GetPoisoned<S2>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000207
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000208 EXPECT_POISONED(*GetPoisoned<S4>());
209 EXPECT_POISONED(*GetPoisoned<S4>());
210 EXPECT_POISONED(*GetPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000211
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000212 EXPECT_POISONED(*GetPoisoned<S8>());
213 EXPECT_POISONED(*GetPoisoned<S8>());
214 EXPECT_POISONED(*GetPoisoned<S8>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000215
216 // ZExt
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000217 EXPECT_POISONED(*GetPoisoned<U1>());
218 EXPECT_POISONED(*GetPoisoned<U1>());
219 EXPECT_POISONED(*GetPoisoned<U1>());
220 EXPECT_POISONED(*GetPoisoned<U2>());
221 EXPECT_POISONED(*GetPoisoned<U2>());
222 EXPECT_POISONED(*GetPoisoned<U4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000223
224 // Unary ops.
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000225 EXPECT_POISONED(- *GetPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000226
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000227 EXPECT_UMR(a_s4[g_zero] = 100 / *GetPoisoned<S4>(0, 1));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000228
229
230 a_s4[g_zero] = 1 - *GetPoisoned<S4>();
231 a_s4[g_zero] = 1 + *GetPoisoned<S4>();
232}
233
234TEST(MemorySanitizer, Phi1) {
235 S4 c;
236 if (g_one) {
237 c = *GetPoisoned<S4>();
238 } else {
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000239 break_optimization(0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000240 c = 0;
241 }
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000242 EXPECT_POISONED(c);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000243}
244
245TEST(MemorySanitizer, Phi2) {
246 S4 i = *GetPoisoned<S4>();
247 S4 n = g_one;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000248 EXPECT_UMR(for (; i < g_one; i++););
249 EXPECT_POISONED(i);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000250}
251
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000252NOINLINE void Arg1ExpectUMR(S4 a1) { EXPECT_POISONED(a1); }
253NOINLINE void Arg2ExpectUMR(S4 a1, S4 a2) { EXPECT_POISONED(a2); }
254NOINLINE void Arg3ExpectUMR(S1 a1, S4 a2, S8 a3) { EXPECT_POISONED(a3); }
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000255
256TEST(MemorySanitizer, ArgTest) {
257 Arg1ExpectUMR(*GetPoisoned<S4>());
258 Arg2ExpectUMR(0, *GetPoisoned<S4>());
259 Arg3ExpectUMR(0, 1, *GetPoisoned<S8>());
260}
261
262
263TEST(MemorySanitizer, CallAndRet) {
264 if (!__msan_has_dynamic_component()) return;
265 ReturnPoisoned<S1>();
266 ReturnPoisoned<S2>();
267 ReturnPoisoned<S4>();
268 ReturnPoisoned<S8>();
269
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000270 EXPECT_POISONED(ReturnPoisoned<S1>());
271 EXPECT_POISONED(ReturnPoisoned<S2>());
272 EXPECT_POISONED(ReturnPoisoned<S4>());
273 EXPECT_POISONED(ReturnPoisoned<S8>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000274}
275
276// malloc() in the following test may be optimized to produce a compile-time
277// undef value. Check that we trap on the volatile assignment anyway.
278TEST(MemorySanitizer, DISABLED_MallocNoIdent) {
279 S4 *x = (int*)malloc(sizeof(S4));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000280 EXPECT_POISONED(*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000281 free(x);
282}
283
284TEST(MemorySanitizer, Malloc) {
285 S4 *x = (int*)Ident(malloc(sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000286 EXPECT_POISONED(*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000287 free(x);
288}
289
290TEST(MemorySanitizer, Realloc) {
291 S4 *x = (int*)Ident(realloc(0, sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000292 EXPECT_POISONED(x[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000293 x[0] = 1;
294 x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000295 EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
296 EXPECT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000297 x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000298 EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
299 EXPECT_POISONED(x[2]);
300 EXPECT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000301 x[2] = 1; // Init this here. Check that after realloc it is poisoned again.
302 x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000303 EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
304 EXPECT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000305 x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000306 EXPECT_POISONED(x[1]);
307 EXPECT_POISONED(x[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000308 free(x);
309}
310
311TEST(MemorySanitizer, Calloc) {
312 S4 *x = (int*)Ident(calloc(1, sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000313 EXPECT_NOT_POISONED(*x); // Should not be poisoned.
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000314 // EXPECT_EQ(0, *x);
315 free(x);
316}
317
318TEST(MemorySanitizer, AndOr) {
319 U4 *p = GetPoisoned<U4>();
320 // We poison two bytes in the midle of a 4-byte word to make the test
321 // correct regardless of endianness.
322 ((U1*)p)[1] = 0;
323 ((U1*)p)[2] = 0xff;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000324 EXPECT_NOT_POISONED(*p & 0x00ffff00);
325 EXPECT_NOT_POISONED(*p & 0x00ff0000);
326 EXPECT_NOT_POISONED(*p & 0x0000ff00);
327 EXPECT_POISONED(*p & 0xff000000);
328 EXPECT_POISONED(*p & 0x000000ff);
329 EXPECT_POISONED(*p & 0x0000ffff);
330 EXPECT_POISONED(*p & 0xffff0000);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000331
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000332 EXPECT_NOT_POISONED(*p | 0xff0000ff);
333 EXPECT_NOT_POISONED(*p | 0xff00ffff);
334 EXPECT_NOT_POISONED(*p | 0xffff00ff);
335 EXPECT_POISONED(*p | 0xff000000);
336 EXPECT_POISONED(*p | 0x000000ff);
337 EXPECT_POISONED(*p | 0x0000ffff);
338 EXPECT_POISONED(*p | 0xffff0000);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000339
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000340 EXPECT_POISONED(*GetPoisoned<bool>() & *GetPoisoned<bool>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000341}
342
343template<class T>
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000344static bool applyNot(T value, T shadow) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000345 __msan_partial_poison(&value, &shadow, sizeof(T));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000346 return !value;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000347}
348
349TEST(MemorySanitizer, Not) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000350 EXPECT_NOT_POISONED(applyNot<U4>(0x0, 0x0));
351 EXPECT_NOT_POISONED(applyNot<U4>(0xFFFFFFFF, 0x0));
352 EXPECT_POISONED(applyNot<U4>(0xFFFFFFFF, 0xFFFFFFFF));
353 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0FFFFFFF));
354 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00FFFFFF));
355 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0000FFFF));
356 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00000000));
357 EXPECT_POISONED(applyNot<U4>(0xFF000000, 0xFF000000));
358 EXPECT_NOT_POISONED(applyNot<U4>(0xFF800000, 0xFF000000));
359 EXPECT_POISONED(applyNot<U4>(0x00008000, 0x00008000));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000360
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000361 EXPECT_NOT_POISONED(applyNot<U1>(0x0, 0x0));
362 EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0xFE));
363 EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0x0));
364 EXPECT_POISONED(applyNot<U1>(0xFF, 0xFF));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000365
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000366 EXPECT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-1)));
367 EXPECT_NOT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-2)));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000368}
369
370TEST(MemorySanitizer, Shift) {
371 U4 *up = GetPoisoned<U4>();
372 ((U1*)up)[0] = 0;
373 ((U1*)up)[3] = 0xff;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000374 EXPECT_NOT_POISONED(*up >> 30);
375 EXPECT_NOT_POISONED(*up >> 24);
376 EXPECT_POISONED(*up >> 23);
377 EXPECT_POISONED(*up >> 10);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000378
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000379 EXPECT_NOT_POISONED(*up << 30);
380 EXPECT_NOT_POISONED(*up << 24);
381 EXPECT_POISONED(*up << 23);
382 EXPECT_POISONED(*up << 10);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000383
384 S4 *sp = (S4*)up;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000385 EXPECT_NOT_POISONED(*sp >> 30);
386 EXPECT_NOT_POISONED(*sp >> 24);
387 EXPECT_POISONED(*sp >> 23);
388 EXPECT_POISONED(*sp >> 10);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000389
390 sp = GetPoisoned<S4>();
391 ((S1*)sp)[1] = 0;
392 ((S1*)sp)[2] = 0;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000393 EXPECT_POISONED(*sp >> 31);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000394
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000395 EXPECT_POISONED(100 >> *GetPoisoned<S4>());
396 EXPECT_POISONED(100U >> *GetPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000397}
398
399NOINLINE static int GetPoisonedZero() {
400 int *zero = new int;
401 *zero = 0;
402 __msan_poison(zero, sizeof(*zero));
403 int res = *zero;
404 delete zero;
405 return res;
406}
407
408TEST(MemorySanitizer, LoadFromDirtyAddress) {
409 int *a = new int;
410 *a = 0;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000411 EXPECT_UMR(break_optimization((void*)(U8)a[GetPoisonedZero()]));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000412 delete a;
413}
414
415TEST(MemorySanitizer, StoreToDirtyAddress) {
416 int *a = new int;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000417 EXPECT_UMR(a[GetPoisonedZero()] = 0);
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000418 break_optimization(a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000419 delete a;
420}
421
422
423NOINLINE void StackTestFunc() {
424 S4 p4;
425 S4 ok4 = 1;
426 S2 p2;
427 S2 ok2 = 1;
428 S1 p1;
429 S1 ok1 = 1;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000430 break_optimization(&p4);
431 break_optimization(&ok4);
432 break_optimization(&p2);
433 break_optimization(&ok2);
434 break_optimization(&p1);
435 break_optimization(&ok1);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000436
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000437 EXPECT_POISONED(p4);
438 EXPECT_POISONED(p2);
439 EXPECT_POISONED(p1);
440 EXPECT_NOT_POISONED(ok1);
441 EXPECT_NOT_POISONED(ok2);
442 EXPECT_NOT_POISONED(ok4);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000443}
444
445TEST(MemorySanitizer, StackTest) {
446 StackTestFunc();
447}
448
449NOINLINE void StackStressFunc() {
450 int foo[10000];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000451 break_optimization(foo);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000452}
453
454TEST(MemorySanitizer, DISABLED_StackStressTest) {
455 for (int i = 0; i < 1000000; i++)
456 StackStressFunc();
457}
458
459template<class T>
460void TestFloatingPoint() {
461 static volatile T v;
462 static T g[100];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000463 break_optimization(&g);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000464 T *x = GetPoisoned<T>();
465 T *y = GetPoisoned<T>(1);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000466 EXPECT_POISONED(*x);
467 EXPECT_POISONED((long long)*x);
468 EXPECT_POISONED((int)*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000469 g[0] = *x;
470 g[1] = *x + *y;
471 g[2] = *x - *y;
472 g[3] = *x * *y;
473}
474
475TEST(MemorySanitizer, FloatingPointTest) {
476 TestFloatingPoint<float>();
477 TestFloatingPoint<double>();
478}
479
480TEST(MemorySanitizer, DynMem) {
481 S4 x = 0;
482 S4 *y = GetPoisoned<S4>();
483 memcpy(y, &x, g_one * sizeof(S4));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000484 EXPECT_NOT_POISONED(*y);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000485}
486
487static char *DynRetTestStr;
488
489TEST(MemorySanitizer, DynRet) {
490 if (!__msan_has_dynamic_component()) return;
491 ReturnPoisoned<S8>();
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000492 EXPECT_NOT_POISONED(clearenv());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000493}
494
495
496TEST(MemorySanitizer, DynRet1) {
497 if (!__msan_has_dynamic_component()) return;
498 ReturnPoisoned<S8>();
499}
500
501struct LargeStruct {
502 S4 x[10];
503};
504
505NOINLINE
506LargeStruct LargeRetTest() {
507 LargeStruct res;
508 res.x[0] = *GetPoisoned<S4>();
509 res.x[1] = *GetPoisoned<S4>();
510 res.x[2] = *GetPoisoned<S4>();
511 res.x[3] = *GetPoisoned<S4>();
512 res.x[4] = *GetPoisoned<S4>();
513 res.x[5] = *GetPoisoned<S4>();
514 res.x[6] = *GetPoisoned<S4>();
515 res.x[7] = *GetPoisoned<S4>();
516 res.x[8] = *GetPoisoned<S4>();
517 res.x[9] = *GetPoisoned<S4>();
518 return res;
519}
520
521TEST(MemorySanitizer, LargeRet) {
522 LargeStruct a = LargeRetTest();
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000523 EXPECT_POISONED(a.x[0]);
524 EXPECT_POISONED(a.x[9]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000525}
526
527TEST(MemorySanitizer, fread) {
528 char *x = new char[32];
529 FILE *f = fopen("/proc/self/stat", "r");
530 assert(f);
531 fread(x, 1, 32, f);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000532 EXPECT_NOT_POISONED(x[0]);
533 EXPECT_NOT_POISONED(x[16]);
534 EXPECT_NOT_POISONED(x[31]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000535 fclose(f);
536 delete x;
537}
538
539TEST(MemorySanitizer, read) {
540 char *x = new char[32];
541 int fd = open("/proc/self/stat", O_RDONLY);
542 assert(fd > 0);
543 int sz = read(fd, x, 32);
544 assert(sz == 32);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000545 EXPECT_NOT_POISONED(x[0]);
546 EXPECT_NOT_POISONED(x[16]);
547 EXPECT_NOT_POISONED(x[31]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000548 close(fd);
549 delete x;
550}
551
552TEST(MemorySanitizer, pread) {
553 char *x = new char[32];
554 int fd = open("/proc/self/stat", O_RDONLY);
555 assert(fd > 0);
556 int sz = pread(fd, x, 32, 0);
557 assert(sz == 32);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000558 EXPECT_NOT_POISONED(x[0]);
559 EXPECT_NOT_POISONED(x[16]);
560 EXPECT_NOT_POISONED(x[31]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000561 close(fd);
562 delete x;
563}
564
565// FIXME: fails now.
566TEST(MemorySanitizer, DISABLED_ioctl) {
567 struct winsize ws;
568 EXPECT_EQ(ioctl(2, TIOCGWINSZ, &ws), 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000569 EXPECT_NOT_POISONED(ws.ws_col);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000570}
571
572TEST(MemorySanitizer, readlink) {
573 char *x = new char[1000];
574 readlink("/proc/self/exe", x, 1000);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000575 EXPECT_NOT_POISONED(x[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000576 delete [] x;
577}
578
579
580TEST(MemorySanitizer, stat) {
581 struct stat* st = new struct stat;
582 int res = stat("/proc/self/stat", st);
583 assert(!res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000584 EXPECT_NOT_POISONED(st->st_dev);
585 EXPECT_NOT_POISONED(st->st_mode);
586 EXPECT_NOT_POISONED(st->st_size);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000587}
588
589TEST(MemorySanitizer, statfs) {
590 struct statfs* st = new struct statfs;
591 int res = statfs("/", st);
592 assert(!res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000593 EXPECT_NOT_POISONED(st->f_type);
594 EXPECT_NOT_POISONED(st->f_bfree);
595 EXPECT_NOT_POISONED(st->f_namelen);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000596}
597
598TEST(MemorySanitizer, pipe) {
599 int* pipefd = new int[2];
600 int res = pipe(pipefd);
601 assert(!res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000602 EXPECT_NOT_POISONED(pipefd[0]);
603 EXPECT_NOT_POISONED(pipefd[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000604 close(pipefd[0]);
605 close(pipefd[1]);
606}
607
608TEST(MemorySanitizer, getcwd) {
609 char path[PATH_MAX + 1];
610 char* res = getcwd(path, sizeof(path));
611 assert(res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000612 EXPECT_NOT_POISONED(path[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000613}
614
Evgeniy Stepanov7eed04c2013-02-12 14:36:22 +0000615TEST(MemorySanitizer, getcwd_gnu) {
616 char* res = getcwd(NULL, 0);
617 assert(res);
618 EXPECT_NOT_POISONED(res[0]);
619 free(res);
620}
621
Evgeniy Stepanovd97a15a2013-03-14 12:49:23 +0000622TEST(MemorySanitizer, readdir) {
623 DIR *dir = opendir(".");
624 struct dirent *d = readdir(dir);
625 assert(d);
626 EXPECT_NOT_POISONED(d->d_name[0]);
627 closedir(dir);
628}
629
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000630TEST(MemorySanitizer, realpath) {
631 const char* relpath = ".";
632 char path[PATH_MAX + 1];
633 char* res = realpath(relpath, path);
634 assert(res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000635 EXPECT_NOT_POISONED(path[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000636}
637
638TEST(MemorySanitizer, memcpy) {
639 char* x = new char[2];
640 char* y = new char[2];
641 x[0] = 1;
642 x[1] = *GetPoisoned<char>();
643 memcpy(y, x, 2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000644 EXPECT_NOT_POISONED(y[0]);
645 EXPECT_POISONED(y[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000646}
647
648TEST(MemorySanitizer, memmove) {
649 char* x = new char[2];
650 char* y = new char[2];
651 x[0] = 1;
652 x[1] = *GetPoisoned<char>();
653 memmove(y, x, 2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000654 EXPECT_NOT_POISONED(y[0]);
655 EXPECT_POISONED(y[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000656}
657
658TEST(MemorySanitizer, strdup) {
Evgeniy Stepanov8aa1ae02013-03-14 11:10:36 +0000659 char buf[4] = "abc";
660 __msan_poison(buf + 2, sizeof(*buf));
661 char *x = strdup(buf);
662 EXPECT_NOT_POISONED(x[0]);
663 EXPECT_NOT_POISONED(x[1]);
664 EXPECT_POISONED(x[2]);
665 EXPECT_NOT_POISONED(x[3]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000666 free(x);
667}
668
Evgeniy Stepanov8aa1ae02013-03-14 11:10:36 +0000669TEST(MemorySanitizer, strndup) {
670 char buf[4] = "abc";
671 __msan_poison(buf + 2, sizeof(*buf));
672 char *x = strndup(buf, 3);
673 EXPECT_NOT_POISONED(x[0]);
674 EXPECT_NOT_POISONED(x[1]);
675 EXPECT_POISONED(x[2]);
676 EXPECT_NOT_POISONED(x[3]);
677 free(x);
678}
679
680TEST(MemorySanitizer, strndup_short) {
681 char buf[4] = "abc";
682 __msan_poison(buf + 1, sizeof(*buf));
683 __msan_poison(buf + 2, sizeof(*buf));
684 char *x = strndup(buf, 2);
685 EXPECT_NOT_POISONED(x[0]);
686 EXPECT_POISONED(x[1]);
Evgeniy Stepanov1d21bd12013-03-14 11:58:13 +0000687 EXPECT_NOT_POISONED(x[2]);
Evgeniy Stepanov8aa1ae02013-03-14 11:10:36 +0000688 free(x);
689}
690
691
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000692template<class T, int size>
693void TestOverlapMemmove() {
694 T *x = new T[size];
695 assert(size >= 3);
696 x[2] = 0;
697 memmove(x, x + 1, (size - 1) * sizeof(T));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000698 EXPECT_NOT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000699 if (!__msan_has_dynamic_component()) {
700 // FIXME: under DR we will lose this information
701 // because accesses in memmove will unpoisin the shadow.
702 // We need to use our own memove implementation instead of libc's.
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000703 EXPECT_POISONED(x[0]);
704 EXPECT_POISONED(x[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000705 }
706 delete [] x;
707}
708
709TEST(MemorySanitizer, overlap_memmove) {
710 TestOverlapMemmove<U1, 10>();
711 TestOverlapMemmove<U1, 1000>();
712 TestOverlapMemmove<U8, 4>();
713 TestOverlapMemmove<U8, 1000>();
714}
715
716TEST(MemorySanitizer, strcpy) { // NOLINT
717 char* x = new char[3];
718 char* y = new char[3];
719 x[0] = 'a';
720 x[1] = *GetPoisoned<char>(1, 1);
721 x[2] = 0;
722 strcpy(y, x); // NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000723 EXPECT_NOT_POISONED(y[0]);
724 EXPECT_POISONED(y[1]);
725 EXPECT_NOT_POISONED(y[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000726}
727
728TEST(MemorySanitizer, strncpy) { // NOLINT
729 char* x = new char[3];
730 char* y = new char[3];
731 x[0] = 'a';
732 x[1] = *GetPoisoned<char>(1, 1);
733 x[2] = 0;
734 strncpy(y, x, 2); // NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000735 EXPECT_NOT_POISONED(y[0]);
736 EXPECT_POISONED(y[1]);
737 EXPECT_POISONED(y[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000738}
739
740TEST(MemorySanitizer, strtol) {
741 char *e;
742 assert(1 == strtol("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000743 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000744}
745
746TEST(MemorySanitizer, strtoll) {
747 char *e;
748 assert(1 == strtoll("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000749 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000750}
751
752TEST(MemorySanitizer, strtoul) {
753 char *e;
754 assert(1 == strtoul("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000755 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000756}
757
758TEST(MemorySanitizer, strtoull) {
759 char *e;
760 assert(1 == strtoull("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000761 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000762}
763
Evgeniy Stepanove03345b2013-01-17 13:42:17 +0000764TEST(MemorySanitizer, strtod) {
765 char *e;
766 assert(0 != strtod("1.5", &e));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000767 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +0000768}
769
770TEST(MemorySanitizer, strtof) {
771 char *e;
772 assert(0 != strtof("1.5", &e));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000773 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +0000774}
775
776TEST(MemorySanitizer, strtold) {
777 char *e;
778 assert(0 != strtold("1.5", &e));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000779 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +0000780}
781
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000782TEST(MemorySanitizer, sprintf) { // NOLINT
783 char buff[10];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000784 break_optimization(buff);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000785 EXPECT_POISONED(buff[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000786 int res = sprintf(buff, "%d", 1234567); // NOLINT
787 assert(res == 7);
788 assert(buff[0] == '1');
789 assert(buff[1] == '2');
790 assert(buff[2] == '3');
791 assert(buff[6] == '7');
792 assert(buff[7] == 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000793 EXPECT_POISONED(buff[8]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000794}
795
796TEST(MemorySanitizer, snprintf) {
797 char buff[10];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000798 break_optimization(buff);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000799 EXPECT_POISONED(buff[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000800 int res = snprintf(buff, sizeof(buff), "%d", 1234567);
801 assert(res == 7);
802 assert(buff[0] == '1');
803 assert(buff[1] == '2');
804 assert(buff[2] == '3');
805 assert(buff[6] == '7');
806 assert(buff[7] == 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000807 EXPECT_POISONED(buff[8]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000808}
809
810TEST(MemorySanitizer, swprintf) {
811 wchar_t buff[10];
812 assert(sizeof(wchar_t) == 4);
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000813 break_optimization(buff);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000814 EXPECT_POISONED(buff[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000815 int res = swprintf(buff, 9, L"%d", 1234567);
816 assert(res == 7);
817 assert(buff[0] == '1');
818 assert(buff[1] == '2');
819 assert(buff[2] == '3');
820 assert(buff[6] == '7');
821 assert(buff[7] == 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000822 EXPECT_POISONED(buff[8]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000823}
824
825TEST(MemorySanitizer, wcstombs) {
826 const wchar_t *x = L"abc";
827 char buff[10];
828 int res = wcstombs(buff, x, 4);
829 EXPECT_EQ(res, 3);
830 EXPECT_EQ(buff[0], 'a');
831 EXPECT_EQ(buff[1], 'b');
832 EXPECT_EQ(buff[2], 'c');
833}
834
835TEST(MemorySanitizer, gettimeofday) {
836 struct timeval tv;
837 struct timezone tz;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000838 break_optimization(&tv);
839 break_optimization(&tz);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000840 assert(sizeof(tv) == 16);
841 assert(sizeof(tz) == 8);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000842 EXPECT_POISONED(tv.tv_sec);
843 EXPECT_POISONED(tv.tv_usec);
844 EXPECT_POISONED(tz.tz_minuteswest);
845 EXPECT_POISONED(tz.tz_dsttime);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000846 assert(0 == gettimeofday(&tv, &tz));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000847 EXPECT_NOT_POISONED(tv.tv_sec);
848 EXPECT_NOT_POISONED(tv.tv_usec);
849 EXPECT_NOT_POISONED(tz.tz_minuteswest);
850 EXPECT_NOT_POISONED(tz.tz_dsttime);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000851}
852
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000853TEST(MemorySanitizer, clock_gettime) {
854 struct timespec tp;
855 EXPECT_POISONED(tp.tv_sec);
856 EXPECT_POISONED(tp.tv_nsec);
857 assert(0 == clock_gettime(CLOCK_REALTIME, &tp));
858 EXPECT_NOT_POISONED(tp.tv_sec);
859 EXPECT_NOT_POISONED(tp.tv_nsec);
860}
861
862TEST(MemorySanitizer, getitimer) {
863 struct itimerval it1, it2;
864 int res;
865 EXPECT_POISONED(it1.it_interval.tv_sec);
866 EXPECT_POISONED(it1.it_interval.tv_usec);
867 EXPECT_POISONED(it1.it_value.tv_sec);
868 EXPECT_POISONED(it1.it_value.tv_usec);
869 res = getitimer(ITIMER_VIRTUAL, &it1);
870 assert(!res);
871 EXPECT_NOT_POISONED(it1.it_interval.tv_sec);
872 EXPECT_NOT_POISONED(it1.it_interval.tv_usec);
873 EXPECT_NOT_POISONED(it1.it_value.tv_sec);
874 EXPECT_NOT_POISONED(it1.it_value.tv_usec);
875
876 it1.it_interval.tv_sec = it1.it_value.tv_sec = 10000;
877 it1.it_interval.tv_usec = it1.it_value.tv_usec = 0;
878
879 res = setitimer(ITIMER_VIRTUAL, &it1, &it2);
880 assert(!res);
881 EXPECT_NOT_POISONED(it2.it_interval.tv_sec);
882 EXPECT_NOT_POISONED(it2.it_interval.tv_usec);
883 EXPECT_NOT_POISONED(it2.it_value.tv_sec);
884 EXPECT_NOT_POISONED(it2.it_value.tv_usec);
885
886 // Check that old_value can be 0, and disable the timer.
887 memset(&it1, 0, sizeof(it1));
888 res = setitimer(ITIMER_VIRTUAL, &it1, 0);
889 assert(!res);
890}
891
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000892TEST(MemorySanitizer, localtime) {
893 time_t t = 123;
894 struct tm *time = localtime(&t);
895 assert(time != 0);
896 EXPECT_NOT_POISONED(time->tm_sec);
897 EXPECT_NOT_POISONED(time->tm_hour);
898 EXPECT_NOT_POISONED(time->tm_year);
899 EXPECT_NOT_POISONED(time->tm_isdst);
900}
901
902TEST(MemorySanitizer, localtime_r) {
903 time_t t = 123;
904 struct tm time;
905 struct tm *res = localtime_r(&t, &time);
906 assert(res != 0);
907 EXPECT_NOT_POISONED(time.tm_sec);
908 EXPECT_NOT_POISONED(time.tm_hour);
909 EXPECT_NOT_POISONED(time.tm_year);
910 EXPECT_NOT_POISONED(time.tm_isdst);
911}
912
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000913TEST(MemorySanitizer, mmap) {
914 const int size = 4096;
915 void *p1, *p2;
916 p1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
917 __msan_poison(p1, size);
918 munmap(p1, size);
919 for (int i = 0; i < 1000; i++) {
920 p2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
921 if (p2 == p1)
922 break;
923 else
924 munmap(p2, size);
925 }
926 if (p1 == p2) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000927 EXPECT_NOT_POISONED(*(char*)p2);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000928 munmap(p2, size);
929 }
930}
931
932// FIXME: enable and add ecvt.
933// FIXME: check why msandr does nt handle fcvt.
934TEST(MemorySanitizer, fcvt) {
935 int a, b;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000936 break_optimization(&a);
937 break_optimization(&b);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000938 EXPECT_POISONED(a);
939 EXPECT_POISONED(b);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000940 char *str = fcvt(12345.6789, 10, &a, &b);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000941 EXPECT_NOT_POISONED(a);
942 EXPECT_NOT_POISONED(b);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000943}
944
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000945TEST(MemorySanitizer, frexp) {
946 int x;
947 x = *GetPoisoned<int>();
948 double r = frexp(1.1, &x);
949 EXPECT_NOT_POISONED(r);
950 EXPECT_NOT_POISONED(x);
951
952 x = *GetPoisoned<int>();
953 float rf = frexpf(1.1, &x);
954 EXPECT_NOT_POISONED(rf);
955 EXPECT_NOT_POISONED(x);
956
957 x = *GetPoisoned<int>();
958 double rl = frexpl(1.1, &x);
959 EXPECT_NOT_POISONED(rl);
960 EXPECT_NOT_POISONED(x);
961}
962
Evgeniy Stepanov06658ea2013-04-04 08:22:52 +0000963namespace {
964
965static int cnt;
966
967void SigactionHandler(int signo, siginfo_t* si, void* uc) {
968 assert(signo == SIGPROF);
969 assert(si);
970 EXPECT_NOT_POISONED(si->si_errno);
971 EXPECT_NOT_POISONED(si->si_pid);
972#if __linux__
973# if defined(__x86_64__)
974 EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_RIP]);
975# elif defined(__i386__)
976 EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_EIP]);
977# endif
978#endif
979 ++cnt;
980}
981
982TEST(MemorySanitizer, sigaction) {
983 struct sigaction act = {};
984 act.sa_flags |= SA_SIGINFO;
985 act.sa_sigaction = &SigactionHandler;
986 sigaction(SIGPROF, &act, 0);
987
988 kill(getpid(), SIGPROF);
989
990 act.sa_flags &= ~SA_SIGINFO;
991 act.sa_handler = SIG_DFL;
992 sigaction(SIGPROF, &act, 0);
993
994 act.sa_flags &= ~SA_SIGINFO;
995 act.sa_handler = SIG_IGN;
996 sigaction(SIGPROF, &act, 0);
997 kill(getpid(), SIGPROF);
998
999 act.sa_flags |= SA_SIGINFO;
1000 act.sa_sigaction = &SigactionHandler;
1001 sigaction(SIGPROF, &act, 0);
1002 kill(getpid(), SIGPROF);
1003
1004 act.sa_flags &= ~SA_SIGINFO;
1005 act.sa_handler = SIG_DFL;
1006 sigaction(SIGPROF, &act, 0);
1007 EXPECT_EQ(2, cnt);
1008}
1009
1010} // namespace
1011
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001012struct StructWithDtor {
1013 ~StructWithDtor();
1014};
1015
1016NOINLINE StructWithDtor::~StructWithDtor() {
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001017 break_optimization(0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001018}
1019
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001020TEST(MemorySanitizer, Invoke) {
1021 StructWithDtor s; // Will cause the calls to become invokes.
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001022 EXPECT_NOT_POISONED(0);
1023 EXPECT_POISONED(*GetPoisoned<int>());
1024 EXPECT_NOT_POISONED(0);
1025 EXPECT_POISONED(*GetPoisoned<int>());
1026 EXPECT_POISONED(ReturnPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001027}
1028
1029TEST(MemorySanitizer, ptrtoint) {
1030 // Test that shadow is propagated through pointer-to-integer conversion.
1031 void* p = (void*)0xABCD;
1032 __msan_poison(((char*)&p) + 1, sizeof(p));
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001033 EXPECT_NOT_POISONED((((uintptr_t)p) & 0xFF) == 0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001034
1035 void* q = (void*)0xABCD;
1036 __msan_poison(&q, sizeof(q) - 1);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001037 EXPECT_POISONED((((uintptr_t)q) & 0xFF) == 0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001038}
1039
1040static void vaargsfn2(int guard, ...) {
1041 va_list vl;
1042 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001043 EXPECT_NOT_POISONED(va_arg(vl, int));
1044 EXPECT_NOT_POISONED(va_arg(vl, int));
1045 EXPECT_NOT_POISONED(va_arg(vl, int));
1046 EXPECT_POISONED(va_arg(vl, double));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001047 va_end(vl);
1048}
1049
1050static void vaargsfn(int guard, ...) {
1051 va_list vl;
1052 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001053 EXPECT_NOT_POISONED(va_arg(vl, int));
1054 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001055 // The following call will overwrite __msan_param_tls.
1056 // Checks after it test that arg shadow was somehow saved across the call.
1057 vaargsfn2(1, 2, 3, 4, *GetPoisoned<double>());
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001058 EXPECT_NOT_POISONED(va_arg(vl, int));
1059 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001060 va_end(vl);
1061}
1062
1063TEST(MemorySanitizer, VAArgTest) {
1064 int* x = GetPoisoned<int>();
1065 int* y = GetPoisoned<int>(4);
1066 vaargsfn(1, 13, *x, 42, *y);
1067}
1068
1069static void vaargsfn_many(int guard, ...) {
1070 va_list vl;
1071 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001072 EXPECT_NOT_POISONED(va_arg(vl, int));
1073 EXPECT_POISONED(va_arg(vl, int));
1074 EXPECT_NOT_POISONED(va_arg(vl, int));
1075 EXPECT_NOT_POISONED(va_arg(vl, int));
1076 EXPECT_NOT_POISONED(va_arg(vl, int));
1077 EXPECT_NOT_POISONED(va_arg(vl, int));
1078 EXPECT_NOT_POISONED(va_arg(vl, int));
1079 EXPECT_NOT_POISONED(va_arg(vl, int));
1080 EXPECT_NOT_POISONED(va_arg(vl, int));
1081 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001082 va_end(vl);
1083}
1084
1085TEST(MemorySanitizer, VAArgManyTest) {
1086 int* x = GetPoisoned<int>();
1087 int* y = GetPoisoned<int>(4);
1088 vaargsfn_many(1, 2, *x, 3, 4, 5, 6, 7, 8, 9, *y);
1089}
1090
1091static void vaargsfn_pass2(va_list vl) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001092 EXPECT_NOT_POISONED(va_arg(vl, int));
1093 EXPECT_NOT_POISONED(va_arg(vl, int));
1094 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001095}
1096
1097static void vaargsfn_pass(int guard, ...) {
1098 va_list vl;
1099 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001100 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001101 vaargsfn_pass2(vl);
1102 va_end(vl);
1103}
1104
1105TEST(MemorySanitizer, VAArgPass) {
1106 int* x = GetPoisoned<int>();
1107 int* y = GetPoisoned<int>(4);
1108 vaargsfn_pass(1, *x, 2, 3, *y);
1109}
1110
1111static void vaargsfn_copy2(va_list vl) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001112 EXPECT_NOT_POISONED(va_arg(vl, int));
1113 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001114}
1115
1116static void vaargsfn_copy(int guard, ...) {
1117 va_list vl;
1118 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001119 EXPECT_NOT_POISONED(va_arg(vl, int));
1120 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001121 va_list vl2;
1122 va_copy(vl2, vl);
1123 vaargsfn_copy2(vl2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001124 EXPECT_NOT_POISONED(va_arg(vl, int));
1125 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001126 va_end(vl);
1127}
1128
1129TEST(MemorySanitizer, VAArgCopy) {
1130 int* x = GetPoisoned<int>();
1131 int* y = GetPoisoned<int>(4);
1132 vaargsfn_copy(1, 2, *x, 3, *y);
1133}
1134
1135static void vaargsfn_ptr(int guard, ...) {
1136 va_list vl;
1137 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001138 EXPECT_NOT_POISONED(va_arg(vl, int*));
1139 EXPECT_POISONED(va_arg(vl, int*));
1140 EXPECT_NOT_POISONED(va_arg(vl, int*));
1141 EXPECT_POISONED(va_arg(vl, double*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001142 va_end(vl);
1143}
1144
1145TEST(MemorySanitizer, VAArgPtr) {
1146 int** x = GetPoisoned<int*>();
1147 double** y = GetPoisoned<double*>(8);
1148 int z;
1149 vaargsfn_ptr(1, &z, *x, &z, *y);
1150}
1151
1152static void vaargsfn_overflow(int guard, ...) {
1153 va_list vl;
1154 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001155 EXPECT_NOT_POISONED(va_arg(vl, int));
1156 EXPECT_NOT_POISONED(va_arg(vl, int));
1157 EXPECT_POISONED(va_arg(vl, int));
1158 EXPECT_NOT_POISONED(va_arg(vl, int));
1159 EXPECT_NOT_POISONED(va_arg(vl, int));
1160 EXPECT_NOT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001161
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001162 EXPECT_NOT_POISONED(va_arg(vl, double));
1163 EXPECT_NOT_POISONED(va_arg(vl, double));
1164 EXPECT_NOT_POISONED(va_arg(vl, double));
1165 EXPECT_POISONED(va_arg(vl, double));
1166 EXPECT_NOT_POISONED(va_arg(vl, double));
1167 EXPECT_POISONED(va_arg(vl, int*));
1168 EXPECT_NOT_POISONED(va_arg(vl, double));
1169 EXPECT_NOT_POISONED(va_arg(vl, double));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001170
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001171 EXPECT_POISONED(va_arg(vl, int));
1172 EXPECT_POISONED(va_arg(vl, double));
1173 EXPECT_POISONED(va_arg(vl, int*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001174
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001175 EXPECT_NOT_POISONED(va_arg(vl, int));
1176 EXPECT_NOT_POISONED(va_arg(vl, double));
1177 EXPECT_NOT_POISONED(va_arg(vl, int*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001178
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001179 EXPECT_POISONED(va_arg(vl, int));
1180 EXPECT_POISONED(va_arg(vl, double));
1181 EXPECT_POISONED(va_arg(vl, int*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001182
1183 va_end(vl);
1184}
1185
1186TEST(MemorySanitizer, VAArgOverflow) {
1187 int* x = GetPoisoned<int>();
1188 double* y = GetPoisoned<double>(8);
1189 int** p = GetPoisoned<int*>(16);
1190 int z;
1191 vaargsfn_overflow(1,
1192 1, 2, *x, 4, 5, 6,
1193 1.1, 2.2, 3.3, *y, 5.5, *p, 7.7, 8.8,
1194 // the following args will overflow for sure
1195 *x, *y, *p,
1196 7, 9.9, &z,
1197 *x, *y, *p);
1198}
1199
1200static void vaargsfn_tlsoverwrite2(int guard, ...) {
1201 va_list vl;
1202 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001203 EXPECT_NOT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001204 va_end(vl);
1205}
1206
1207static void vaargsfn_tlsoverwrite(int guard, ...) {
1208 // This call will overwrite TLS contents unless it's backed up somewhere.
1209 vaargsfn_tlsoverwrite2(2, 42);
1210 va_list vl;
1211 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001212 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001213 va_end(vl);
1214}
1215
1216TEST(MemorySanitizer, VAArgTLSOverwrite) {
1217 int* x = GetPoisoned<int>();
1218 vaargsfn_tlsoverwrite(1, *x);
1219}
1220
1221struct StructByVal {
1222 int a, b, c, d, e, f;
1223};
1224
1225NOINLINE void StructByValTestFunc(struct StructByVal s) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001226 EXPECT_NOT_POISONED(s.a);
1227 EXPECT_POISONED(s.b);
1228 EXPECT_NOT_POISONED(s.c);
1229 EXPECT_POISONED(s.d);
1230 EXPECT_NOT_POISONED(s.e);
1231 EXPECT_POISONED(s.f);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001232}
1233
1234NOINLINE void StructByValTestFunc1(struct StructByVal s) {
1235 StructByValTestFunc(s);
1236}
1237
1238NOINLINE void StructByValTestFunc2(int z, struct StructByVal s) {
1239 StructByValTestFunc(s);
1240}
1241
1242TEST(MemorySanitizer, StructByVal) {
1243 // Large aggregates are passed as "byval" pointer argument in LLVM.
1244 struct StructByVal s;
1245 s.a = 1;
1246 s.b = *GetPoisoned<int>();
1247 s.c = 2;
1248 s.d = *GetPoisoned<int>();
1249 s.e = 3;
1250 s.f = *GetPoisoned<int>();
1251 StructByValTestFunc(s);
1252 StructByValTestFunc1(s);
1253 StructByValTestFunc2(0, s);
1254}
1255
1256
1257#if MSAN_HAS_M128
1258NOINLINE __m128i m128Eq(__m128i *a, __m128i *b) { return *a == *b; }
1259NOINLINE __m128i m128Lt(__m128i *a, __m128i *b) { return *a < *b; }
1260TEST(MemorySanitizer, m128) {
1261 __m128i a = _mm_set1_epi16(0x1234);
1262 __m128i b = _mm_set1_epi16(0x7890);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001263 EXPECT_NOT_POISONED(m128Eq(&a, &b));
1264 EXPECT_NOT_POISONED(m128Lt(&a, &b));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001265}
1266// FIXME: add more tests for __m128i.
1267#endif // MSAN_HAS_M128
1268
1269// We should not complain when copying this poisoned hole.
1270struct StructWithHole {
1271 U4 a;
1272 // 4-byte hole.
1273 U8 b;
1274};
1275
1276NOINLINE StructWithHole ReturnStructWithHole() {
1277 StructWithHole res;
1278 __msan_poison(&res, sizeof(res));
1279 res.a = 1;
1280 res.b = 2;
1281 return res;
1282}
1283
1284TEST(MemorySanitizer, StructWithHole) {
1285 StructWithHole a = ReturnStructWithHole();
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001286 break_optimization(&a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001287}
1288
1289template <class T>
1290NOINLINE T ReturnStruct() {
1291 T res;
1292 __msan_poison(&res, sizeof(res));
1293 res.a = 1;
1294 return res;
1295}
1296
1297template <class T>
1298NOINLINE void TestReturnStruct() {
1299 T s1 = ReturnStruct<T>();
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001300 EXPECT_NOT_POISONED(s1.a);
1301 EXPECT_POISONED(s1.b);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001302}
1303
1304struct SSS1 {
1305 int a, b, c;
1306};
1307struct SSS2 {
1308 int b, a, c;
1309};
1310struct SSS3 {
1311 int b, c, a;
1312};
1313struct SSS4 {
1314 int c, b, a;
1315};
1316
1317struct SSS5 {
1318 int a;
1319 float b;
1320};
1321struct SSS6 {
1322 int a;
1323 double b;
1324};
1325struct SSS7 {
1326 S8 b;
1327 int a;
1328};
1329struct SSS8 {
1330 S2 b;
1331 S8 a;
1332};
1333
1334TEST(MemorySanitizer, IntStruct3) {
1335 TestReturnStruct<SSS1>();
1336 TestReturnStruct<SSS2>();
1337 TestReturnStruct<SSS3>();
1338 TestReturnStruct<SSS4>();
1339 TestReturnStruct<SSS5>();
1340 TestReturnStruct<SSS6>();
1341 TestReturnStruct<SSS7>();
1342 TestReturnStruct<SSS8>();
1343}
1344
1345struct LongStruct {
1346 U1 a1, b1;
1347 U2 a2, b2;
1348 U4 a4, b4;
1349 U8 a8, b8;
1350};
1351
1352NOINLINE LongStruct ReturnLongStruct1() {
1353 LongStruct res;
1354 __msan_poison(&res, sizeof(res));
1355 res.a1 = res.a2 = res.a4 = res.a8 = 111;
1356 // leaves b1, .., b8 poisoned.
1357 return res;
1358}
1359
1360NOINLINE LongStruct ReturnLongStruct2() {
1361 LongStruct res;
1362 __msan_poison(&res, sizeof(res));
1363 res.b1 = res.b2 = res.b4 = res.b8 = 111;
1364 // leaves a1, .., a8 poisoned.
1365 return res;
1366}
1367
1368TEST(MemorySanitizer, LongStruct) {
1369 LongStruct s1 = ReturnLongStruct1();
1370 __msan_print_shadow(&s1, sizeof(s1));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001371 EXPECT_NOT_POISONED(s1.a1);
1372 EXPECT_NOT_POISONED(s1.a2);
1373 EXPECT_NOT_POISONED(s1.a4);
1374 EXPECT_NOT_POISONED(s1.a8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001375
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001376 EXPECT_POISONED(s1.b1);
1377 EXPECT_POISONED(s1.b2);
1378 EXPECT_POISONED(s1.b4);
1379 EXPECT_POISONED(s1.b8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001380
1381 LongStruct s2 = ReturnLongStruct2();
1382 __msan_print_shadow(&s2, sizeof(s2));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001383 EXPECT_NOT_POISONED(s2.b1);
1384 EXPECT_NOT_POISONED(s2.b2);
1385 EXPECT_NOT_POISONED(s2.b4);
1386 EXPECT_NOT_POISONED(s2.b8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001387
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001388 EXPECT_POISONED(s2.a1);
1389 EXPECT_POISONED(s2.a2);
1390 EXPECT_POISONED(s2.a4);
1391 EXPECT_POISONED(s2.a8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001392}
1393
1394TEST(MemorySanitizer, getrlimit) {
1395 struct rlimit limit;
1396 __msan_poison(&limit, sizeof(limit));
1397 int result = getrlimit(RLIMIT_DATA, &limit);
1398 assert(result == 0);
1399 volatile rlim_t t;
1400 t = limit.rlim_cur;
1401 t = limit.rlim_max;
1402}
1403
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001404TEST(MemorySanitizer, getrusage) {
1405 struct rusage usage;
1406 __msan_poison(&usage, sizeof(usage));
1407 int result = getrusage(RUSAGE_SELF, &usage);
1408 assert(result == 0);
1409 volatile struct timeval t;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001410 EXPECT_NOT_POISONED(usage.ru_utime.tv_sec);
1411 EXPECT_NOT_POISONED(usage.ru_utime.tv_usec);
1412 EXPECT_NOT_POISONED(usage.ru_stime.tv_sec);
1413 EXPECT_NOT_POISONED(usage.ru_stime.tv_usec);
1414 EXPECT_NOT_POISONED(usage.ru_maxrss);
1415 EXPECT_NOT_POISONED(usage.ru_minflt);
1416 EXPECT_NOT_POISONED(usage.ru_majflt);
1417 EXPECT_NOT_POISONED(usage.ru_inblock);
1418 EXPECT_NOT_POISONED(usage.ru_oublock);
1419 EXPECT_NOT_POISONED(usage.ru_nvcsw);
1420 EXPECT_NOT_POISONED(usage.ru_nivcsw);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001421}
1422
1423static void dladdr_testfn() {}
1424
1425TEST(MemorySanitizer, dladdr) {
1426 Dl_info info;
1427 __msan_poison(&info, sizeof(info));
1428 int result = dladdr((const void*)dladdr_testfn, &info);
1429 assert(result != 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001430 EXPECT_NOT_POISONED((unsigned long)info.dli_fname);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001431 if (info.dli_fname)
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001432 EXPECT_NOT_POISONED(strlen(info.dli_fname));
1433 EXPECT_NOT_POISONED((unsigned long)info.dli_fbase);
1434 EXPECT_NOT_POISONED((unsigned long)info.dli_sname);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001435 if (info.dli_sname)
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001436 EXPECT_NOT_POISONED(strlen(info.dli_sname));
1437 EXPECT_NOT_POISONED((unsigned long)info.dli_saddr);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001438}
1439
Evgeniy Stepanov86b57222013-03-22 08:49:36 +00001440namespace {
Reid Kleckner0f92deb2013-03-11 18:07:42 +00001441#ifdef __GLIBC__
1442extern "C" {
1443 extern void *__libc_stack_end;
1444}
1445
1446static char **GetArgv(void) {
1447 uintptr_t *stack_end = (uintptr_t *)__libc_stack_end;
1448 return (char**)(stack_end + 1);
1449}
1450
1451#else // __GLIBC__
1452# error "TODO: port this"
1453#endif
1454
1455TEST(MemorySanitizer, dlopen) {
1456 // Compute the path to our loadable DSO. We assume it's in the same
1457 // directory. Only use string routines that we intercept so far to do this.
1458 char **argv = GetArgv();
1459 const char *basename = "libmsan_loadable.x86_64.so";
1460 size_t path_max = strlen(argv[0]) + 1 + strlen(basename) + 1;
1461 char *path = new char[path_max];
1462 char *last_slash = strrchr(argv[0], '/');
1463 assert(last_slash);
1464 snprintf(path, path_max, "%.*s/%s", int(last_slash - argv[0]),
1465 argv[0], basename);
1466
1467 // We need to clear shadow for globals when doing dlopen. In order to test
1468 // this, we have to poison the shadow for the DSO before we load it. In
1469 // general this is difficult, but the loader tends to reload things in the
1470 // same place, so we open, close, and then reopen. The global should always
1471 // start out clean after dlopen.
1472 for (int i = 0; i < 2; i++) {
1473 void *lib = dlopen(path, RTLD_LAZY);
1474 if (lib == NULL) {
1475 printf("dlerror: %s\n", dlerror());
1476 assert(lib != NULL);
1477 }
1478 void **(*get_dso_global)() = (void **(*)())dlsym(lib, "get_dso_global");
1479 assert(get_dso_global);
1480 void **dso_global = get_dso_global();
1481 EXPECT_NOT_POISONED(*dso_global);
1482 __msan_poison(dso_global, sizeof(*dso_global));
1483 EXPECT_POISONED(*dso_global);
1484 dlclose(lib);
1485 }
1486
1487 delete[] path;
1488}
Evgeniy Stepanov6c503b92013-03-22 11:59:49 +00001489
1490// Regression test for a crash in dlopen() interceptor.
1491TEST(MemorySanitizer, dlopenFailed) {
1492 const char *path = "/libmsan_loadable_does_not_exist.x86_64.so";
1493 void *lib = dlopen(path, RTLD_LAZY);
1494 ASSERT_EQ(0, lib);
1495}
Evgeniy Stepanov86b57222013-03-22 08:49:36 +00001496} // namespace
Reid Kleckner0f92deb2013-03-11 18:07:42 +00001497
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +00001498TEST(MemorySanitizer, scanf) {
1499 const char *input = "42 hello";
1500 int* d = new int;
1501 char* s = new char[7];
1502 int res = sscanf(input, "%d %5s", d, s);
1503 printf("res %d\n", res);
1504 assert(res == 2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001505 EXPECT_NOT_POISONED(*d);
1506 EXPECT_NOT_POISONED(s[0]);
1507 EXPECT_NOT_POISONED(s[1]);
1508 EXPECT_NOT_POISONED(s[2]);
1509 EXPECT_NOT_POISONED(s[3]);
1510 EXPECT_NOT_POISONED(s[4]);
1511 EXPECT_NOT_POISONED(s[5]);
1512 EXPECT_POISONED(s[6]);
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +00001513 delete s;
1514 delete d;
1515}
1516
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00001517static void *SimpleThread_threadfn(void* data) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001518 return new int;
1519}
1520
1521TEST(MemorySanitizer, SimpleThread) {
1522 pthread_t t;
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00001523 void *p;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001524 int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL);
1525 assert(!res);
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +00001526 EXPECT_NOT_POISONED(t);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001527 res = pthread_join(t, &p);
1528 assert(!res);
1529 if (!__msan_has_dynamic_component()) // FIXME: intercept pthread_join (?).
1530 __msan_unpoison(&p, sizeof(p));
1531 delete (int*)p;
1532}
1533
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00001534static void *SmallStackThread_threadfn(void* data) {
Evgeniy Stepanov10fd3222013-03-13 09:01:40 +00001535 return 0;
1536}
1537
1538TEST(MemorySanitizer, SmallStackThread) {
1539 pthread_attr_t attr;
1540 pthread_t t;
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00001541 void *p;
Evgeniy Stepanov10fd3222013-03-13 09:01:40 +00001542 int res;
1543 res = pthread_attr_init(&attr);
1544 ASSERT_EQ(0, res);
1545 res = pthread_attr_setstacksize(&attr, 64 * 1024);
1546 ASSERT_EQ(0, res);
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00001547 res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);
Evgeniy Stepanov10fd3222013-03-13 09:01:40 +00001548 ASSERT_EQ(0, res);
1549 res = pthread_join(t, &p);
1550 ASSERT_EQ(0, res);
1551 res = pthread_attr_destroy(&attr);
1552 ASSERT_EQ(0, res);
1553}
1554
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00001555TEST(MemorySanitizer, PreAllocatedStackThread) {
1556 pthread_attr_t attr;
1557 pthread_t t;
1558 int res;
1559 res = pthread_attr_init(&attr);
1560 ASSERT_EQ(0, res);
1561 void *stack;
1562 const size_t kStackSize = 64 * 1024;
1563 res = posix_memalign(&stack, 4096, kStackSize);
1564 ASSERT_EQ(0, res);
1565 res = pthread_attr_setstack(&attr, stack, kStackSize);
1566 ASSERT_EQ(0, res);
1567 // A small self-allocated stack can not be extended by the tool.
1568 // In this case pthread_create is expected to fail.
1569 res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);
1570 EXPECT_NE(0, res);
1571 res = pthread_attr_destroy(&attr);
1572 ASSERT_EQ(0, res);
1573}
1574
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001575TEST(MemorySanitizer, uname) {
1576 struct utsname u;
1577 int res = uname(&u);
1578 assert(!res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001579 EXPECT_NOT_POISONED(strlen(u.sysname));
1580 EXPECT_NOT_POISONED(strlen(u.nodename));
1581 EXPECT_NOT_POISONED(strlen(u.release));
1582 EXPECT_NOT_POISONED(strlen(u.version));
1583 EXPECT_NOT_POISONED(strlen(u.machine));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001584}
1585
Evgeniy Stepanov95d05882013-01-23 10:43:38 +00001586TEST(MemorySanitizer, gethostname) {
1587 char buf[100];
1588 int res = gethostname(buf, 100);
1589 assert(!res);
1590 EXPECT_NOT_POISONED(strlen(buf));
1591}
1592
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +00001593TEST(MemorySanitizer, getpwuid) {
1594 struct passwd *p = getpwuid(0); // root
1595 assert(p);
1596 EXPECT_NOT_POISONED(p->pw_name);
1597 assert(p->pw_name);
1598 EXPECT_NOT_POISONED(p->pw_name[0]);
1599 EXPECT_NOT_POISONED(p->pw_uid);
1600 assert(p->pw_uid == 0);
1601}
1602
1603TEST(MemorySanitizer, getpwnam_r) {
1604 struct passwd pwd;
1605 struct passwd *pwdres;
1606 char buf[10000];
1607 int res = getpwnam_r("root", &pwd, buf, sizeof(buf), &pwdres);
1608 assert(!res);
1609 EXPECT_NOT_POISONED(pwd.pw_name);
1610 assert(pwd.pw_name);
1611 EXPECT_NOT_POISONED(pwd.pw_name[0]);
1612 EXPECT_NOT_POISONED(pwd.pw_uid);
1613 assert(pwd.pw_uid == 0);
1614}
1615
1616TEST(MemorySanitizer, getpwnam_r_positive) {
1617 struct passwd pwd;
1618 struct passwd *pwdres;
1619 char s[5];
1620 strncpy(s, "abcd", 5);
1621 __msan_poison(s, 5);
1622 char buf[10000];
1623 int res;
1624 EXPECT_UMR(res = getpwnam_r(s, &pwd, buf, sizeof(buf), &pwdres));
1625}
1626
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001627template<class T>
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001628static bool applySlt(T value, T shadow) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001629 __msan_partial_poison(&value, &shadow, sizeof(T));
1630 volatile bool zzz = true;
1631 // This "|| zzz" trick somehow makes LLVM emit "icmp slt" instead of
1632 // a shift-and-trunc to get at the highest bit.
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001633 volatile bool v = value < 0 || zzz;
1634 return v;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001635}
1636
1637TEST(MemorySanitizer, SignedCompareWithZero) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001638 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xF));
1639 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFF));
1640 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFFFFFF));
1641 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0x7FFFFFF));
1642 EXPECT_UMR(applySlt<S4>(0xF, 0x80FFFFFF));
1643 EXPECT_UMR(applySlt<S4>(0xF, 0xFFFFFFFF));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001644}
1645
Evgeniy Stepanov9a22a3d2013-01-25 15:39:11 +00001646template <class T, class S>
1647static T poisoned(T Va, S Sa) {
1648 char SIZE_CHECK1[(ssize_t)sizeof(T) - (ssize_t)sizeof(S)];
1649 char SIZE_CHECK2[(ssize_t)sizeof(S) - (ssize_t)sizeof(T)];
1650 T a;
1651 a = Va;
1652 __msan_partial_poison(&a, &Sa, sizeof(T));
1653 return a;
1654}
1655
1656TEST(MemorySanitizer, ICmpRelational) {
1657 EXPECT_NOT_POISONED(poisoned(0, 0) < poisoned(0, 0));
1658 EXPECT_NOT_POISONED(poisoned(0U, 0) < poisoned(0U, 0));
1659 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) < poisoned(0LL, 0LLU));
1660 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) < poisoned(0LLU, 0LLU));
1661 EXPECT_POISONED(poisoned(0xFF, 0xFF) < poisoned(0xFF, 0xFF));
1662 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <
1663 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
1664 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <
1665 poisoned(-1, 0xFFFFFFFFU));
1666
1667 EXPECT_NOT_POISONED(poisoned(0, 0) <= poisoned(0, 0));
1668 EXPECT_NOT_POISONED(poisoned(0U, 0) <= poisoned(0U, 0));
1669 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) <= poisoned(0LL, 0LLU));
1670 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) <= poisoned(0LLU, 0LLU));
1671 EXPECT_POISONED(poisoned(0xFF, 0xFF) <= poisoned(0xFF, 0xFF));
1672 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <=
1673 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
1674 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <=
1675 poisoned(-1, 0xFFFFFFFFU));
1676
1677 EXPECT_NOT_POISONED(poisoned(0, 0) > poisoned(0, 0));
1678 EXPECT_NOT_POISONED(poisoned(0U, 0) > poisoned(0U, 0));
1679 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) > poisoned(0LL, 0LLU));
1680 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) > poisoned(0LLU, 0LLU));
1681 EXPECT_POISONED(poisoned(0xFF, 0xFF) > poisoned(0xFF, 0xFF));
1682 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >
1683 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
1684 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >
1685 poisoned(-1, 0xFFFFFFFFU));
1686
1687 EXPECT_NOT_POISONED(poisoned(0, 0) >= poisoned(0, 0));
1688 EXPECT_NOT_POISONED(poisoned(0U, 0) >= poisoned(0U, 0));
1689 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) >= poisoned(0LL, 0LLU));
1690 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) >= poisoned(0LLU, 0LLU));
1691 EXPECT_POISONED(poisoned(0xFF, 0xFF) >= poisoned(0xFF, 0xFF));
1692 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >=
1693 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
1694 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >=
1695 poisoned(-1, 0xFFFFFFFFU));
1696
Evgeniy Stepanov9a22a3d2013-01-25 15:39:11 +00001697 EXPECT_POISONED(poisoned(6, 0xF) > poisoned(7, 0));
1698 EXPECT_POISONED(poisoned(0xF, 0xF) > poisoned(7, 0));
1699
1700 EXPECT_NOT_POISONED(poisoned(-1, 0x80000000U) >= poisoned(-1, 0U));
Evgeniy Stepanov9a22a3d2013-01-25 15:39:11 +00001701}
1702
1703#if MSAN_HAS_M128
1704TEST(MemorySanitizer, ICmpVectorRelational) {
1705 EXPECT_NOT_POISONED(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0)) <
1706 poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0)));
1707 EXPECT_NOT_POISONED(poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0)) <
1708 poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0)));
1709 EXPECT_POISONED(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF)) <
1710 poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF)));
1711 EXPECT_POISONED(poisoned(_mm_set1_epi16(6), _mm_set1_epi16(0xF)) >
1712 poisoned(_mm_set1_epi16(7), _mm_set1_epi16(0)));
1713}
1714#endif
1715
Evgeniy Stepanov2efa1422013-01-22 12:31:39 +00001716// Volatile bitfield store is implemented as load-mask-store
1717// Test that we don't warn on the store of (uninitialized) padding.
1718struct VolatileBitfieldStruct {
1719 volatile unsigned x : 1;
1720 unsigned y : 1;
1721};
1722
1723TEST(MemorySanitizer, VolatileBitfield) {
1724 VolatileBitfieldStruct *S = new VolatileBitfieldStruct;
1725 S->x = 1;
Evgeniy Stepanov02f4a942013-01-22 12:33:11 +00001726 EXPECT_NOT_POISONED((unsigned)S->x);
1727 EXPECT_POISONED((unsigned)S->y);
Evgeniy Stepanov2efa1422013-01-22 12:31:39 +00001728}
1729
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001730TEST(MemorySanitizerDr, StoreInDSOTest) {
1731 if (!__msan_has_dynamic_component()) return;
1732 char* s = new char[10];
1733 dso_memfill(s, 9);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001734 EXPECT_NOT_POISONED(s[5]);
1735 EXPECT_POISONED(s[9]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001736}
1737
1738int return_poisoned_int() {
1739 return ReturnPoisoned<U8>();
1740}
1741
1742TEST(MemorySanitizerDr, ReturnFromDSOTest) {
1743 if (!__msan_has_dynamic_component()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001744 EXPECT_NOT_POISONED(dso_callfn(return_poisoned_int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001745}
1746
1747NOINLINE int TrashParamTLS(long long x, long long y, long long z) { //NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001748 EXPECT_POISONED(x);
1749 EXPECT_POISONED(y);
1750 EXPECT_POISONED(z);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001751 return 0;
1752}
1753
1754static int CheckParamTLS(long long x, long long y, long long z) { //NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001755 EXPECT_NOT_POISONED(x);
1756 EXPECT_NOT_POISONED(y);
1757 EXPECT_NOT_POISONED(z);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001758 return 0;
1759}
1760
1761TEST(MemorySanitizerDr, CallFromDSOTest) {
1762 if (!__msan_has_dynamic_component()) return;
1763 S8* x = GetPoisoned<S8>();
1764 S8* y = GetPoisoned<S8>();
1765 S8* z = GetPoisoned<S8>();
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001766 EXPECT_NOT_POISONED(TrashParamTLS(*x, *y, *z));
1767 EXPECT_NOT_POISONED(dso_callfn1(CheckParamTLS));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001768}
1769
1770static void StackStoreInDSOFn(int* x, int* y) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001771 EXPECT_NOT_POISONED(*x);
1772 EXPECT_NOT_POISONED(*y);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001773}
1774
1775TEST(MemorySanitizerDr, StackStoreInDSOTest) {
1776 if (!__msan_has_dynamic_component()) return;
1777 dso_stack_store(StackStoreInDSOFn, 1);
1778}
1779
1780TEST(MemorySanitizerOrigins, SetGet) {
1781 EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins());
1782 if (!TrackingOrigins()) return;
1783 int x;
1784 __msan_set_origin(&x, sizeof(x), 1234);
1785 EXPECT_EQ(1234, __msan_get_origin(&x));
1786 __msan_set_origin(&x, sizeof(x), 5678);
1787 EXPECT_EQ(5678, __msan_get_origin(&x));
1788 __msan_set_origin(&x, sizeof(x), 0);
1789 EXPECT_EQ(0, __msan_get_origin(&x));
1790}
1791
1792namespace {
1793struct S {
1794 U4 dummy;
1795 U2 a;
1796 U2 b;
1797};
1798
1799// http://code.google.com/p/memory-sanitizer/issues/detail?id=6
1800TEST(MemorySanitizerOrigins, DISABLED_InitializedStoreDoesNotChangeOrigin) {
1801 if (!TrackingOrigins()) return;
1802
1803 S s;
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001804 U4 origin = rand(); // NOLINT
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001805 s.a = *GetPoisonedO<U2>(0, origin);
1806 EXPECT_EQ(origin, __msan_get_origin(&s.a));
1807 EXPECT_EQ(origin, __msan_get_origin(&s.b));
1808
1809 s.b = 42;
1810 EXPECT_EQ(origin, __msan_get_origin(&s.a));
1811 EXPECT_EQ(origin, __msan_get_origin(&s.b));
1812}
1813} // namespace
1814
1815template<class T, class BinaryOp>
1816INLINE
1817void BinaryOpOriginTest(BinaryOp op) {
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001818 U4 ox = rand(); //NOLINT
1819 U4 oy = rand(); //NOLINT
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001820 T *x = GetPoisonedO<T>(0, ox, 0);
1821 T *y = GetPoisonedO<T>(1, oy, 0);
1822 T *z = GetPoisonedO<T>(2, 0, 0);
1823
1824 *z = op(*x, *y);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001825 U4 origin = __msan_get_origin(z);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001826 EXPECT_POISONED_O(*z, origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001827 EXPECT_EQ(true, origin == ox || origin == oy);
1828
1829 // y is poisoned, x is not.
1830 *x = 10101;
1831 *y = *GetPoisonedO<T>(1, oy);
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001832 break_optimization(x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001833 __msan_set_origin(z, sizeof(*z), 0);
1834 *z = op(*x, *y);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001835 EXPECT_POISONED_O(*z, oy);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001836 EXPECT_EQ(__msan_get_origin(z), oy);
1837
1838 // x is poisoned, y is not.
1839 *x = *GetPoisonedO<T>(0, ox);
1840 *y = 10101010;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001841 break_optimization(y);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001842 __msan_set_origin(z, sizeof(*z), 0);
1843 *z = op(*x, *y);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001844 EXPECT_POISONED_O(*z, ox);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001845 EXPECT_EQ(__msan_get_origin(z), ox);
1846}
1847
1848template<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; }
1849template<class T> INLINE T ADD(const T &a, const T&b) { return a + b; }
1850template<class T> INLINE T SUB(const T &a, const T&b) { return a - b; }
1851template<class T> INLINE T MUL(const T &a, const T&b) { return a * b; }
1852template<class T> INLINE T AND(const T &a, const T&b) { return a & b; }
1853template<class T> INLINE T OR (const T &a, const T&b) { return a | b; }
1854
1855TEST(MemorySanitizerOrigins, BinaryOp) {
1856 if (!TrackingOrigins()) return;
1857 BinaryOpOriginTest<S8>(XOR<S8>);
1858 BinaryOpOriginTest<U8>(ADD<U8>);
1859 BinaryOpOriginTest<S4>(SUB<S4>);
1860 BinaryOpOriginTest<S4>(MUL<S4>);
1861 BinaryOpOriginTest<U4>(OR<U4>);
1862 BinaryOpOriginTest<U4>(AND<U4>);
1863 BinaryOpOriginTest<double>(ADD<U4>);
1864 BinaryOpOriginTest<float>(ADD<S4>);
1865 BinaryOpOriginTest<double>(ADD<double>);
1866 BinaryOpOriginTest<float>(ADD<double>);
1867}
1868
1869TEST(MemorySanitizerOrigins, Unary) {
1870 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001871 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
1872 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
1873 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
1874 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001875
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001876 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
1877 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
1878 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
1879 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001880
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001881 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
1882 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
1883 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
1884 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001885
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001886 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
1887 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
1888 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
1889 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001890
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001891 EXPECT_POISONED_O((void*)*GetPoisonedO<S8>(0, __LINE__), __LINE__);
1892 EXPECT_POISONED_O((U8)*GetPoisonedO<void*>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001893}
1894
1895TEST(MemorySanitizerOrigins, EQ) {
1896 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001897 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) <= 11, __LINE__);
1898 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) == 11, __LINE__);
1899 EXPECT_POISONED_O(*GetPoisonedO<float>(0, __LINE__) == 1.1, __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001900}
1901
1902TEST(MemorySanitizerOrigins, DIV) {
1903 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001904 EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) / 100, __LINE__);
1905 unsigned o = __LINE__;
1906 EXPECT_UMR_O(volatile unsigned y = 100 / *GetPoisonedO<S4>(0, o, 1), o);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001907}
1908
1909TEST(MemorySanitizerOrigins, SHIFT) {
1910 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001911 EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) >> 10, __LINE__);
1912 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) >> 10, __LINE__);
1913 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) << 10, __LINE__);
1914 EXPECT_POISONED_O(10U << *GetPoisonedO<U8>(0, __LINE__), __LINE__);
1915 EXPECT_POISONED_O(-10 >> *GetPoisonedO<S8>(0, __LINE__), __LINE__);
1916 EXPECT_POISONED_O(-10 << *GetPoisonedO<S8>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001917}
1918
1919template<class T, int N>
1920void MemCpyTest() {
1921 int ox = __LINE__;
1922 T *x = new T[N];
1923 T *y = new T[N];
1924 T *z = new T[N];
1925 __msan_poison(x, N * sizeof(T));
1926 __msan_set_origin(x, N * sizeof(T), ox);
1927 __msan_set_origin(y, N * sizeof(T), 777777);
1928 __msan_set_origin(z, N * sizeof(T), 888888);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001929 EXPECT_NOT_POISONED(x);
1930 memcpy(y, x, N * sizeof(T));
1931 EXPECT_POISONED_O(y[0], ox);
1932 EXPECT_POISONED_O(y[N/2], ox);
1933 EXPECT_POISONED_O(y[N-1], ox);
1934 EXPECT_NOT_POISONED(x);
1935 memmove(z, x, N * sizeof(T));
1936 EXPECT_POISONED_O(z[0], ox);
1937 EXPECT_POISONED_O(z[N/2], ox);
1938 EXPECT_POISONED_O(z[N-1], ox);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001939}
1940
1941TEST(MemorySanitizerOrigins, LargeMemCpy) {
1942 if (!TrackingOrigins()) return;
1943 MemCpyTest<U1, 10000>();
1944 MemCpyTest<U8, 10000>();
1945}
1946
1947TEST(MemorySanitizerOrigins, SmallMemCpy) {
1948 if (!TrackingOrigins()) return;
1949 MemCpyTest<U8, 1>();
1950 MemCpyTest<U8, 2>();
1951 MemCpyTest<U8, 3>();
1952}
1953
1954TEST(MemorySanitizerOrigins, Select) {
1955 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001956 EXPECT_NOT_POISONED(g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__));
1957 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001958 S4 x;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001959 break_optimization(&x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001960 x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;
1961
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001962 EXPECT_POISONED_O(g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);
1963 EXPECT_POISONED_O(g_0 ? 1 : *GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001964}
1965
1966extern "C"
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001967NOINLINE char AllocaTO() {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001968 int ar[100];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001969 break_optimization(ar);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001970 return ar[10];
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001971 // fprintf(stderr, "Descr: %s\n",
1972 // __msan_get_origin_descr_if_stack(__msan_get_origin_tls()));
1973}
1974
1975TEST(MemorySanitizerOrigins, Alloca) {
1976 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001977 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
1978 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
1979 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
1980 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001981}
1982
1983// FIXME: replace with a lit-like test.
1984TEST(MemorySanitizerOrigins, DISABLED_AllocaDeath) {
1985 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001986 EXPECT_DEATH(AllocaTO(), "ORIGIN: stack allocation: ar@AllocaTO");
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001987}
1988
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001989NOINLINE int RetvalOriginTest(U4 origin) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001990 int *a = new int;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001991 break_optimization(a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001992 __msan_set_origin(a, sizeof(*a), origin);
1993 int res = *a;
1994 delete a;
1995 return res;
1996}
1997
1998TEST(MemorySanitizerOrigins, Retval) {
1999 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002000 EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002001}
2002
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002003NOINLINE void ParamOriginTest(int param, U4 origin) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002004 EXPECT_POISONED_O(param, origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002005}
2006
2007TEST(MemorySanitizerOrigins, Param) {
2008 if (!TrackingOrigins()) return;
2009 int *a = new int;
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002010 U4 origin = __LINE__;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00002011 break_optimization(a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002012 __msan_set_origin(a, sizeof(*a), origin);
2013 ParamOriginTest(*a, origin);
2014 delete a;
2015}
2016
2017TEST(MemorySanitizerOrigins, Invoke) {
2018 if (!TrackingOrigins()) return;
2019 StructWithDtor s; // Will cause the calls to become invokes.
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002020 EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002021}
2022
2023TEST(MemorySanitizerOrigins, strlen) {
2024 S8 alignment;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00002025 break_optimization(&alignment);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002026 char x[4] = {'a', 'b', 0, 0};
2027 __msan_poison(&x[2], 1);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002028 U4 origin = __LINE__;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002029 __msan_set_origin(x, sizeof(x), origin);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002030 EXPECT_UMR_O(volatile unsigned y = strlen(x), origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002031}
2032
2033TEST(MemorySanitizerOrigins, wcslen) {
2034 wchar_t w[3] = {'a', 'b', 0};
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002035 U4 origin = __LINE__;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002036 __msan_set_origin(w, sizeof(w), origin);
2037 __msan_poison(&w[2], sizeof(wchar_t));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002038 EXPECT_UMR_O(volatile unsigned y = wcslen(w), origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002039}
2040
2041#if MSAN_HAS_M128
2042TEST(MemorySanitizerOrigins, StoreIntrinsic) {
2043 __m128 x, y;
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002044 U4 origin = __LINE__;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002045 __msan_set_origin(&x, sizeof(x), origin);
2046 __msan_poison(&x, sizeof(x));
2047 __builtin_ia32_storeups((float*)&y, x);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002048 EXPECT_POISONED_O(y, origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002049}
2050#endif
2051
2052NOINLINE void RecursiveMalloc(int depth) {
2053 static int count;
2054 count++;
2055 if ((count % (1024 * 1024)) == 0)
2056 printf("RecursiveMalloc: %d\n", count);
2057 int *x1 = new int;
2058 int *x2 = new int;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00002059 break_optimization(x1);
2060 break_optimization(x2);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002061 if (depth > 0) {
2062 RecursiveMalloc(depth-1);
2063 RecursiveMalloc(depth-1);
2064 }
2065 delete x1;
2066 delete x2;
2067}
2068
Kostya Serebryany65199f12013-01-25 11:46:22 +00002069TEST(MemorySanitizer, CallocOverflow) {
2070 size_t kArraySize = 4096;
2071 volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
2072 volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
2073 void *p = calloc(kArraySize, kArraySize2); // Should return 0.
2074 EXPECT_EQ(0L, Ident(p));
2075}
2076
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002077TEST(MemorySanitizerStress, DISABLED_MallocStackTrace) {
2078 RecursiveMalloc(22);
2079}