blob: f185a31de30817e4958ec8c7f46c23fa3580747f [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
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +000022#include <inttypes.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000023#include <stdlib.h>
24#include <stdarg.h>
25#include <stdio.h>
26#include <assert.h>
27#include <wchar.h>
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +000028#include <math.h>
Evgeniy Stepanov97160a82013-09-02 09:24:53 +000029#include <malloc.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000030
Evgeniy Stepanov9530eb72013-04-23 14:05:15 +000031#include <arpa/inet.h>
Evgeniy Stepanove03345b2013-01-17 13:42:17 +000032#include <dlfcn.h>
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +000033#include <grp.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000034#include <unistd.h>
Evgeniy Stepanov2bba4ef2013-05-16 13:00:25 +000035#include <link.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000036#include <limits.h>
37#include <sys/time.h>
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +000038#include <poll.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000039#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42#include <sys/resource.h>
43#include <sys/ioctl.h>
Evgeniy Stepanov5cee73e2013-10-18 11:14:16 +000044#include <sys/statvfs.h>
Evgeniy Stepanov359d7fc2013-06-24 14:25:33 +000045#include <sys/sysinfo.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000046#include <sys/utsname.h>
47#include <sys/mman.h>
48#include <sys/vfs.h>
Evgeniy Stepanovd97a15a2013-03-14 12:49:23 +000049#include <dirent.h>
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +000050#include <pwd.h>
Evgeniy Stepanov134fe8a2013-04-08 13:45:12 +000051#include <sys/socket.h>
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +000052#include <netdb.h>
Evgeniy Stepanovc5a38552013-09-24 14:38:22 +000053#include <wordexp.h>
Evgeniy Stepanov4d7297d2013-10-18 09:41:43 +000054#include <mntent.h>
Evgeniy Stepanov369a9a62013-10-23 13:57:47 +000055#include <netinet/ether.h>
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000056
57#if defined(__i386__) || defined(__x86_64__)
58# include <emmintrin.h>
59# define MSAN_HAS_M128 1
60#else
61# define MSAN_HAS_M128 0
62#endif
63
Evgeniy Stepanov97160a82013-09-02 09:24:53 +000064static const int kPageSize = 4096;
65
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000066typedef unsigned char U1;
67typedef unsigned short U2; // NOLINT
68typedef unsigned int U4;
69typedef unsigned long long U8; // NOLINT
70typedef signed char S1;
71typedef signed short S2; // NOLINT
72typedef signed int S4;
73typedef signed long long S8; // NOLINT
74#define NOINLINE __attribute__((noinline))
75#define INLINE __attribute__((always_inline))
76
Evgeniy Stepanov11929002013-01-22 12:29:00 +000077static bool TrackingOrigins() {
78 S8 x;
79 __msan_set_origin(&x, sizeof(x), 0x1234);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +000080 U4 origin = __msan_get_origin(&x);
Evgeniy Stepanov11929002013-01-22 12:29:00 +000081 __msan_set_origin(&x, sizeof(x), 0);
82 return origin == 0x1234;
83}
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000084
Evgeniy Stepanov11929002013-01-22 12:29:00 +000085#define EXPECT_UMR(action) \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000086 do { \
87 __msan_set_expect_umr(1); \
88 action; \
89 __msan_set_expect_umr(0); \
90 } while (0)
91
Evgeniy Stepanov11929002013-01-22 12:29:00 +000092#define EXPECT_UMR_O(action, origin) \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000093 do { \
94 __msan_set_expect_umr(1); \
95 action; \
96 __msan_set_expect_umr(0); \
97 if (TrackingOrigins()) \
Evgeniy Stepanov12c46932013-01-29 14:33:29 +000098 EXPECT_EQ(origin, __msan_get_umr_origin()); \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +000099 } while (0)
100
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000101#define EXPECT_UMR_S(action, stack_origin) \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000102 do { \
103 __msan_set_expect_umr(1); \
104 action; \
105 __msan_set_expect_umr(0); \
Evgeniy Stepanov250f2212013-01-30 13:12:08 +0000106 U4 id = __msan_get_umr_origin(); \
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000107 const char *str = __msan_get_origin_descr_if_stack(id); \
108 if (!str || strcmp(str, stack_origin)) { \
109 fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s", \
110 id, stack_origin, str); \
111 EXPECT_EQ(1, 0); \
112 } \
113 } while (0)
114
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000115#define EXPECT_POISONED(x) ExpectPoisoned(x)
116
117template<typename T>
118void ExpectPoisoned(const T& t) {
119 EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
120}
121
122#define EXPECT_POISONED_O(x, origin) \
123 ExpectPoisonedWithOrigin(x, origin)
124
125template<typename T>
126void ExpectPoisonedWithOrigin(const T& t, unsigned origin) {
127 EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
128 if (TrackingOrigins())
129 EXPECT_EQ(origin, __msan_get_origin((void*)&t));
130}
131
132#define EXPECT_POISONED_S(x, stack_origin) \
133 ExpectPoisonedWithStackOrigin(x, stack_origin)
134
135template<typename T>
136void ExpectPoisonedWithStackOrigin(const T& t, const char *stack_origin) {
137 EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
Evgeniy Stepanov250f2212013-01-30 13:12:08 +0000138 U4 id = __msan_get_origin((void*)&t);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000139 const char *str = __msan_get_origin_descr_if_stack(id);
140 if (!str || strcmp(str, stack_origin)) {
141 fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s",
142 id, stack_origin, str);
143 EXPECT_EQ(1, 0);
144 }
145}
146
147#define EXPECT_NOT_POISONED(x) ExpectNotPoisoned(x)
148
149template<typename T>
150void ExpectNotPoisoned(const T& t) {
151 EXPECT_EQ(-1, __msan_test_shadow((void*)&t, sizeof(t)));
152}
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000153
154static U8 poisoned_array[100];
155template<class T>
156T *GetPoisoned(int i = 0, T val = 0) {
157 T *res = (T*)&poisoned_array[i];
158 *res = val;
159 __msan_poison(&poisoned_array[i], sizeof(T));
160 return res;
161}
162
163template<class T>
Evgeniy Stepanov250f2212013-01-30 13:12:08 +0000164T *GetPoisonedO(int i, U4 origin, T val = 0) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000165 T *res = (T*)&poisoned_array[i];
166 *res = val;
167 __msan_poison(&poisoned_array[i], sizeof(T));
168 __msan_set_origin(&poisoned_array[i], sizeof(T), origin);
169 return res;
170}
171
172// This function returns its parameter but in such a way that compiler
173// can not prove it.
174template<class T>
175NOINLINE
176static T Ident(T t) {
177 volatile T ret = t;
178 return ret;
179}
180
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000181template<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); }
182
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000183static volatile int g_one = 1;
184static volatile int g_zero = 0;
185static volatile int g_0 = 0;
186static volatile int g_1 = 1;
187
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000188S4 a_s4[100];
189S8 a_s8[100];
190
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000191// Check that malloc poisons memory.
192// A lot of tests below depend on this.
193TEST(MemorySanitizerSanity, PoisonInMalloc) {
194 int *x = (int*)malloc(sizeof(int));
195 EXPECT_POISONED(*x);
196 free(x);
197}
198
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000199TEST(MemorySanitizer, NegativeTest1) {
200 S4 *x = GetPoisoned<S4>();
201 if (g_one)
202 *x = 0;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000203 EXPECT_NOT_POISONED(*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000204}
205
206TEST(MemorySanitizer, PositiveTest1) {
207 // Load to store.
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000208 EXPECT_POISONED(*GetPoisoned<S1>());
209 EXPECT_POISONED(*GetPoisoned<S2>());
210 EXPECT_POISONED(*GetPoisoned<S4>());
211 EXPECT_POISONED(*GetPoisoned<S8>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000212
213 // S->S conversions.
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000214 EXPECT_POISONED(*GetPoisoned<S1>());
215 EXPECT_POISONED(*GetPoisoned<S1>());
216 EXPECT_POISONED(*GetPoisoned<S1>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000217
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000218 EXPECT_POISONED(*GetPoisoned<S2>());
219 EXPECT_POISONED(*GetPoisoned<S2>());
220 EXPECT_POISONED(*GetPoisoned<S2>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000221
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000222 EXPECT_POISONED(*GetPoisoned<S4>());
223 EXPECT_POISONED(*GetPoisoned<S4>());
224 EXPECT_POISONED(*GetPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000225
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000226 EXPECT_POISONED(*GetPoisoned<S8>());
227 EXPECT_POISONED(*GetPoisoned<S8>());
228 EXPECT_POISONED(*GetPoisoned<S8>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000229
230 // ZExt
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000231 EXPECT_POISONED(*GetPoisoned<U1>());
232 EXPECT_POISONED(*GetPoisoned<U1>());
233 EXPECT_POISONED(*GetPoisoned<U1>());
234 EXPECT_POISONED(*GetPoisoned<U2>());
235 EXPECT_POISONED(*GetPoisoned<U2>());
236 EXPECT_POISONED(*GetPoisoned<U4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000237
238 // Unary ops.
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000239 EXPECT_POISONED(- *GetPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000240
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000241 EXPECT_UMR(a_s4[g_zero] = 100 / *GetPoisoned<S4>(0, 1));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000242
243
244 a_s4[g_zero] = 1 - *GetPoisoned<S4>();
245 a_s4[g_zero] = 1 + *GetPoisoned<S4>();
246}
247
248TEST(MemorySanitizer, Phi1) {
249 S4 c;
250 if (g_one) {
251 c = *GetPoisoned<S4>();
252 } else {
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000253 break_optimization(0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000254 c = 0;
255 }
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000256 EXPECT_POISONED(c);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000257}
258
259TEST(MemorySanitizer, Phi2) {
260 S4 i = *GetPoisoned<S4>();
261 S4 n = g_one;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000262 EXPECT_UMR(for (; i < g_one; i++););
263 EXPECT_POISONED(i);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000264}
265
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000266NOINLINE void Arg1ExpectUMR(S4 a1) { EXPECT_POISONED(a1); }
267NOINLINE void Arg2ExpectUMR(S4 a1, S4 a2) { EXPECT_POISONED(a2); }
268NOINLINE void Arg3ExpectUMR(S1 a1, S4 a2, S8 a3) { EXPECT_POISONED(a3); }
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000269
270TEST(MemorySanitizer, ArgTest) {
271 Arg1ExpectUMR(*GetPoisoned<S4>());
272 Arg2ExpectUMR(0, *GetPoisoned<S4>());
273 Arg3ExpectUMR(0, 1, *GetPoisoned<S8>());
274}
275
276
277TEST(MemorySanitizer, CallAndRet) {
278 if (!__msan_has_dynamic_component()) return;
279 ReturnPoisoned<S1>();
280 ReturnPoisoned<S2>();
281 ReturnPoisoned<S4>();
282 ReturnPoisoned<S8>();
283
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000284 EXPECT_POISONED(ReturnPoisoned<S1>());
285 EXPECT_POISONED(ReturnPoisoned<S2>());
286 EXPECT_POISONED(ReturnPoisoned<S4>());
287 EXPECT_POISONED(ReturnPoisoned<S8>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000288}
289
290// malloc() in the following test may be optimized to produce a compile-time
291// undef value. Check that we trap on the volatile assignment anyway.
292TEST(MemorySanitizer, DISABLED_MallocNoIdent) {
293 S4 *x = (int*)malloc(sizeof(S4));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000294 EXPECT_POISONED(*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000295 free(x);
296}
297
298TEST(MemorySanitizer, Malloc) {
299 S4 *x = (int*)Ident(malloc(sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000300 EXPECT_POISONED(*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000301 free(x);
302}
303
304TEST(MemorySanitizer, Realloc) {
305 S4 *x = (int*)Ident(realloc(0, sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000306 EXPECT_POISONED(x[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000307 x[0] = 1;
308 x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000309 EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
310 EXPECT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000311 x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000312 EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
313 EXPECT_POISONED(x[2]);
314 EXPECT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000315 x[2] = 1; // Init this here. Check that after realloc it is poisoned again.
316 x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000317 EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
318 EXPECT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000319 x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000320 EXPECT_POISONED(x[1]);
321 EXPECT_POISONED(x[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000322 free(x);
323}
324
325TEST(MemorySanitizer, Calloc) {
326 S4 *x = (int*)Ident(calloc(1, sizeof(S4)));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000327 EXPECT_NOT_POISONED(*x); // Should not be poisoned.
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000328 // EXPECT_EQ(0, *x);
329 free(x);
330}
331
332TEST(MemorySanitizer, AndOr) {
333 U4 *p = GetPoisoned<U4>();
334 // We poison two bytes in the midle of a 4-byte word to make the test
335 // correct regardless of endianness.
336 ((U1*)p)[1] = 0;
337 ((U1*)p)[2] = 0xff;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000338 EXPECT_NOT_POISONED(*p & 0x00ffff00);
339 EXPECT_NOT_POISONED(*p & 0x00ff0000);
340 EXPECT_NOT_POISONED(*p & 0x0000ff00);
341 EXPECT_POISONED(*p & 0xff000000);
342 EXPECT_POISONED(*p & 0x000000ff);
343 EXPECT_POISONED(*p & 0x0000ffff);
344 EXPECT_POISONED(*p & 0xffff0000);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000345
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000346 EXPECT_NOT_POISONED(*p | 0xff0000ff);
347 EXPECT_NOT_POISONED(*p | 0xff00ffff);
348 EXPECT_NOT_POISONED(*p | 0xffff00ff);
349 EXPECT_POISONED(*p | 0xff000000);
350 EXPECT_POISONED(*p | 0x000000ff);
351 EXPECT_POISONED(*p | 0x0000ffff);
352 EXPECT_POISONED(*p | 0xffff0000);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000353
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000354 EXPECT_POISONED(*GetPoisoned<bool>() & *GetPoisoned<bool>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000355}
356
357template<class T>
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000358static bool applyNot(T value, T shadow) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000359 __msan_partial_poison(&value, &shadow, sizeof(T));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000360 return !value;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000361}
362
363TEST(MemorySanitizer, Not) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000364 EXPECT_NOT_POISONED(applyNot<U4>(0x0, 0x0));
365 EXPECT_NOT_POISONED(applyNot<U4>(0xFFFFFFFF, 0x0));
366 EXPECT_POISONED(applyNot<U4>(0xFFFFFFFF, 0xFFFFFFFF));
367 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0FFFFFFF));
368 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00FFFFFF));
369 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0000FFFF));
370 EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00000000));
371 EXPECT_POISONED(applyNot<U4>(0xFF000000, 0xFF000000));
372 EXPECT_NOT_POISONED(applyNot<U4>(0xFF800000, 0xFF000000));
373 EXPECT_POISONED(applyNot<U4>(0x00008000, 0x00008000));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000374
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000375 EXPECT_NOT_POISONED(applyNot<U1>(0x0, 0x0));
376 EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0xFE));
377 EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0x0));
378 EXPECT_POISONED(applyNot<U1>(0xFF, 0xFF));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000379
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000380 EXPECT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-1)));
381 EXPECT_NOT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-2)));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000382}
383
384TEST(MemorySanitizer, Shift) {
385 U4 *up = GetPoisoned<U4>();
386 ((U1*)up)[0] = 0;
387 ((U1*)up)[3] = 0xff;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000388 EXPECT_NOT_POISONED(*up >> 30);
389 EXPECT_NOT_POISONED(*up >> 24);
390 EXPECT_POISONED(*up >> 23);
391 EXPECT_POISONED(*up >> 10);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000392
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000393 EXPECT_NOT_POISONED(*up << 30);
394 EXPECT_NOT_POISONED(*up << 24);
395 EXPECT_POISONED(*up << 23);
396 EXPECT_POISONED(*up << 10);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000397
398 S4 *sp = (S4*)up;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000399 EXPECT_NOT_POISONED(*sp >> 30);
400 EXPECT_NOT_POISONED(*sp >> 24);
401 EXPECT_POISONED(*sp >> 23);
402 EXPECT_POISONED(*sp >> 10);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000403
404 sp = GetPoisoned<S4>();
405 ((S1*)sp)[1] = 0;
406 ((S1*)sp)[2] = 0;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000407 EXPECT_POISONED(*sp >> 31);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000408
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000409 EXPECT_POISONED(100 >> *GetPoisoned<S4>());
410 EXPECT_POISONED(100U >> *GetPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000411}
412
413NOINLINE static int GetPoisonedZero() {
414 int *zero = new int;
415 *zero = 0;
416 __msan_poison(zero, sizeof(*zero));
417 int res = *zero;
418 delete zero;
419 return res;
420}
421
422TEST(MemorySanitizer, LoadFromDirtyAddress) {
423 int *a = new int;
424 *a = 0;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000425 EXPECT_UMR(break_optimization((void*)(U8)a[GetPoisonedZero()]));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000426 delete a;
427}
428
429TEST(MemorySanitizer, StoreToDirtyAddress) {
430 int *a = new int;
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000431 EXPECT_UMR(a[GetPoisonedZero()] = 0);
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000432 break_optimization(a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000433 delete a;
434}
435
436
437NOINLINE void StackTestFunc() {
438 S4 p4;
439 S4 ok4 = 1;
440 S2 p2;
441 S2 ok2 = 1;
442 S1 p1;
443 S1 ok1 = 1;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000444 break_optimization(&p4);
445 break_optimization(&ok4);
446 break_optimization(&p2);
447 break_optimization(&ok2);
448 break_optimization(&p1);
449 break_optimization(&ok1);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000450
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000451 EXPECT_POISONED(p4);
452 EXPECT_POISONED(p2);
453 EXPECT_POISONED(p1);
454 EXPECT_NOT_POISONED(ok1);
455 EXPECT_NOT_POISONED(ok2);
456 EXPECT_NOT_POISONED(ok4);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000457}
458
459TEST(MemorySanitizer, StackTest) {
460 StackTestFunc();
461}
462
463NOINLINE void StackStressFunc() {
464 int foo[10000];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000465 break_optimization(foo);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000466}
467
468TEST(MemorySanitizer, DISABLED_StackStressTest) {
469 for (int i = 0; i < 1000000; i++)
470 StackStressFunc();
471}
472
473template<class T>
474void TestFloatingPoint() {
475 static volatile T v;
476 static T g[100];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +0000477 break_optimization(&g);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000478 T *x = GetPoisoned<T>();
479 T *y = GetPoisoned<T>(1);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000480 EXPECT_POISONED(*x);
481 EXPECT_POISONED((long long)*x);
482 EXPECT_POISONED((int)*x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000483 g[0] = *x;
484 g[1] = *x + *y;
485 g[2] = *x - *y;
486 g[3] = *x * *y;
487}
488
489TEST(MemorySanitizer, FloatingPointTest) {
490 TestFloatingPoint<float>();
491 TestFloatingPoint<double>();
492}
493
494TEST(MemorySanitizer, DynMem) {
495 S4 x = 0;
496 S4 *y = GetPoisoned<S4>();
497 memcpy(y, &x, g_one * sizeof(S4));
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000498 EXPECT_NOT_POISONED(*y);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000499}
500
501static char *DynRetTestStr;
502
503TEST(MemorySanitizer, DynRet) {
504 if (!__msan_has_dynamic_component()) return;
505 ReturnPoisoned<S8>();
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000506 EXPECT_NOT_POISONED(clearenv());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000507}
508
509
510TEST(MemorySanitizer, DynRet1) {
511 if (!__msan_has_dynamic_component()) return;
512 ReturnPoisoned<S8>();
513}
514
515struct LargeStruct {
516 S4 x[10];
517};
518
519NOINLINE
520LargeStruct LargeRetTest() {
521 LargeStruct res;
522 res.x[0] = *GetPoisoned<S4>();
523 res.x[1] = *GetPoisoned<S4>();
524 res.x[2] = *GetPoisoned<S4>();
525 res.x[3] = *GetPoisoned<S4>();
526 res.x[4] = *GetPoisoned<S4>();
527 res.x[5] = *GetPoisoned<S4>();
528 res.x[6] = *GetPoisoned<S4>();
529 res.x[7] = *GetPoisoned<S4>();
530 res.x[8] = *GetPoisoned<S4>();
531 res.x[9] = *GetPoisoned<S4>();
532 return res;
533}
534
Alexey Samsonov67505a82013-07-16 12:51:53 +0000535TEST(MemorySanitizer, strcmp) {
536 char s1[10];
537 char s2[10];
538 strncpy(s1, "foo", 10);
539 s2[0] = 'f';
540 s2[1] = 'n';
541 EXPECT_GT(strcmp(s1, s2), 0);
542 s2[1] = 'o';
543 int res;
544 EXPECT_UMR(res = strcmp(s1, s2));
545 EXPECT_NOT_POISONED(res);
546 EXPECT_EQ(strncmp(s1, s2, 1), 0);
547}
548
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000549TEST(MemorySanitizer, LargeRet) {
550 LargeStruct a = LargeRetTest();
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000551 EXPECT_POISONED(a.x[0]);
552 EXPECT_POISONED(a.x[9]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000553}
554
Evgeniy Stepanov12049792013-08-08 11:44:05 +0000555TEST(MemorySanitizer, strerror) {
556 char *buf = strerror(EINVAL);
557 EXPECT_NOT_POISONED(strlen(buf));
558 buf = strerror(123456);
559 EXPECT_NOT_POISONED(strlen(buf));
560}
561
562TEST(MemorySanitizer, strerror_r) {
563 errno = 0;
564 char buf[1000];
565 char *res = strerror_r(EINVAL, buf, sizeof(buf));
566 ASSERT_EQ(0, errno);
567 if (!res) res = buf; // POSIX version success.
568 EXPECT_NOT_POISONED(strlen(res));
569}
570
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000571TEST(MemorySanitizer, fread) {
572 char *x = new char[32];
573 FILE *f = fopen("/proc/self/stat", "r");
574 assert(f);
575 fread(x, 1, 32, f);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000576 EXPECT_NOT_POISONED(x[0]);
577 EXPECT_NOT_POISONED(x[16]);
578 EXPECT_NOT_POISONED(x[31]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000579 fclose(f);
580 delete x;
581}
582
583TEST(MemorySanitizer, read) {
584 char *x = new char[32];
585 int fd = open("/proc/self/stat", O_RDONLY);
586 assert(fd > 0);
587 int sz = read(fd, x, 32);
588 assert(sz == 32);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000589 EXPECT_NOT_POISONED(x[0]);
590 EXPECT_NOT_POISONED(x[16]);
591 EXPECT_NOT_POISONED(x[31]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000592 close(fd);
593 delete x;
594}
595
596TEST(MemorySanitizer, pread) {
597 char *x = new char[32];
598 int fd = open("/proc/self/stat", O_RDONLY);
599 assert(fd > 0);
600 int sz = pread(fd, x, 32, 0);
601 assert(sz == 32);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000602 EXPECT_NOT_POISONED(x[0]);
603 EXPECT_NOT_POISONED(x[16]);
604 EXPECT_NOT_POISONED(x[31]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000605 close(fd);
606 delete x;
607}
608
Evgeniy Stepanovb916e6a2013-06-24 10:43:23 +0000609TEST(MemorySanitizer, readv) {
610 char buf[2011];
611 struct iovec iov[2];
612 iov[0].iov_base = buf + 1;
613 iov[0].iov_len = 5;
614 iov[1].iov_base = buf + 10;
615 iov[1].iov_len = 2000;
616 int fd = open("/proc/self/stat", O_RDONLY);
617 assert(fd > 0);
618 int sz = readv(fd, iov, 2);
619 ASSERT_LT(sz, 5 + 2000);
620 ASSERT_GT(sz, iov[0].iov_len);
621 EXPECT_POISONED(buf[0]);
622 EXPECT_NOT_POISONED(buf[1]);
623 EXPECT_NOT_POISONED(buf[5]);
624 EXPECT_POISONED(buf[6]);
625 EXPECT_POISONED(buf[9]);
626 EXPECT_NOT_POISONED(buf[10]);
627 EXPECT_NOT_POISONED(buf[10 + (sz - 1) - 5]);
628 EXPECT_POISONED(buf[11 + (sz - 1) - 5]);
629 close(fd);
630}
631
632TEST(MemorySanitizer, preadv) {
633 char buf[2011];
634 struct iovec iov[2];
635 iov[0].iov_base = buf + 1;
636 iov[0].iov_len = 5;
637 iov[1].iov_base = buf + 10;
638 iov[1].iov_len = 2000;
639 int fd = open("/proc/self/stat", O_RDONLY);
640 assert(fd > 0);
641 int sz = preadv(fd, iov, 2, 3);
642 ASSERT_LT(sz, 5 + 2000);
643 ASSERT_GT(sz, iov[0].iov_len);
644 EXPECT_POISONED(buf[0]);
645 EXPECT_NOT_POISONED(buf[1]);
646 EXPECT_NOT_POISONED(buf[5]);
647 EXPECT_POISONED(buf[6]);
648 EXPECT_POISONED(buf[9]);
649 EXPECT_NOT_POISONED(buf[10]);
650 EXPECT_NOT_POISONED(buf[10 + (sz - 1) - 5]);
651 EXPECT_POISONED(buf[11 + (sz - 1) - 5]);
652 close(fd);
653}
654
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000655// FIXME: fails now.
656TEST(MemorySanitizer, DISABLED_ioctl) {
657 struct winsize ws;
658 EXPECT_EQ(ioctl(2, TIOCGWINSZ, &ws), 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000659 EXPECT_NOT_POISONED(ws.ws_col);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000660}
661
662TEST(MemorySanitizer, readlink) {
663 char *x = new char[1000];
664 readlink("/proc/self/exe", x, 1000);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000665 EXPECT_NOT_POISONED(x[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000666 delete [] x;
667}
668
669
670TEST(MemorySanitizer, stat) {
671 struct stat* st = new struct stat;
672 int res = stat("/proc/self/stat", st);
673 assert(!res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000674 EXPECT_NOT_POISONED(st->st_dev);
675 EXPECT_NOT_POISONED(st->st_mode);
676 EXPECT_NOT_POISONED(st->st_size);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000677}
678
Evgeniy Stepanovbb229422013-09-09 13:40:41 +0000679TEST(MemorySanitizer, fstatat) {
680 struct stat* st = new struct stat;
681 int dirfd = open("/proc/self", O_RDONLY);
682 assert(dirfd > 0);
683 int res = fstatat(dirfd, "stat", st, 0);
684 assert(!res);
685 EXPECT_NOT_POISONED(st->st_dev);
686 EXPECT_NOT_POISONED(st->st_mode);
687 EXPECT_NOT_POISONED(st->st_size);
688 close(dirfd);
689}
690
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000691TEST(MemorySanitizer, statfs) {
Evgeniy Stepanov5cee73e2013-10-18 11:14:16 +0000692 struct statfs st;
693 int res = statfs("/", &st);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000694 assert(!res);
Evgeniy Stepanov5cee73e2013-10-18 11:14:16 +0000695 EXPECT_NOT_POISONED(st.f_type);
696 EXPECT_NOT_POISONED(st.f_bfree);
697 EXPECT_NOT_POISONED(st.f_namelen);
698}
699
700TEST(MemorySanitizer, statvfs) {
701 struct statvfs st;
702 int res = statvfs("/", &st);
703 assert(!res);
704 EXPECT_NOT_POISONED(st.f_bsize);
705 EXPECT_NOT_POISONED(st.f_blocks);
706 EXPECT_NOT_POISONED(st.f_bfree);
707 EXPECT_NOT_POISONED(st.f_namemax);
708}
709
710TEST(MemorySanitizer, fstatvfs) {
711 struct statvfs st;
712 int fd = open("/", O_RDONLY | O_DIRECTORY);
713 int res = fstatvfs(fd, &st);
714 assert(!res);
715 EXPECT_NOT_POISONED(st.f_bsize);
716 EXPECT_NOT_POISONED(st.f_blocks);
717 EXPECT_NOT_POISONED(st.f_bfree);
718 EXPECT_NOT_POISONED(st.f_namemax);
719 close(fd);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000720}
721
722TEST(MemorySanitizer, pipe) {
723 int* pipefd = new int[2];
724 int res = pipe(pipefd);
725 assert(!res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +0000726 EXPECT_NOT_POISONED(pipefd[0]);
727 EXPECT_NOT_POISONED(pipefd[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +0000728 close(pipefd[0]);
729 close(pipefd[1]);
730}
731
Evgeniy Stepanov134fe8a2013-04-08 13:45:12 +0000732TEST(MemorySanitizer, pipe2) {
733 int* pipefd = new int[2];
734 int res = pipe2(pipefd, O_NONBLOCK);
735 assert(!res);
736 EXPECT_NOT_POISONED(pipefd[0]);
737 EXPECT_NOT_POISONED(pipefd[1]);
738 close(pipefd[0]);
739 close(pipefd[1]);
740}
741
742TEST(MemorySanitizer, socketpair) {
743 int sv[2];
744 int res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
745 assert(!res);
746 EXPECT_NOT_POISONED(sv[0]);
747 EXPECT_NOT_POISONED(sv[1]);
748 close(sv[0]);
749 close(sv[1]);
750}
751
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +0000752TEST(MemorySanitizer, poll) {
753 int* pipefd = new int[2];
754 int res = pipe(pipefd);
755 ASSERT_EQ(0, res);
756
757 char data = 42;
758 res = write(pipefd[1], &data, 1);
759 ASSERT_EQ(1, res);
760
761 pollfd fds[2];
762 fds[0].fd = pipefd[0];
763 fds[0].events = POLLIN;
764 fds[1].fd = pipefd[1];
765 fds[1].events = POLLIN;
766 res = poll(fds, 2, 500);
767 ASSERT_EQ(1, res);
768 EXPECT_NOT_POISONED(fds[0].revents);
769 EXPECT_NOT_POISONED(fds[1].revents);
770
771 close(pipefd[0]);
772 close(pipefd[1]);
773}
774
Evgeniy Stepanov47177ef2013-08-27 11:10:20 +0000775TEST(MemorySanitizer, ppoll) {
776 int* pipefd = new int[2];
777 int res = pipe(pipefd);
778 ASSERT_EQ(0, res);
779
780 char data = 42;
781 res = write(pipefd[1], &data, 1);
782 ASSERT_EQ(1, res);
783
784 pollfd fds[2];
785 fds[0].fd = pipefd[0];
786 fds[0].events = POLLIN;
787 fds[1].fd = pipefd[1];
788 fds[1].events = POLLIN;
789 sigset_t ss;
790 sigemptyset(&ss);
791 res = ppoll(fds, 2, NULL, &ss);
792 ASSERT_EQ(1, res);
793 EXPECT_NOT_POISONED(fds[0].revents);
794 EXPECT_NOT_POISONED(fds[1].revents);
795
796 close(pipefd[0]);
797 close(pipefd[1]);
798}
799
Evgeniy Stepanove18e3f02013-08-12 13:19:53 +0000800TEST(MemorySanitizer, poll_positive) {
801 int* pipefd = new int[2];
802 int res = pipe(pipefd);
803 ASSERT_EQ(0, res);
804
805 pollfd fds[2];
806 fds[0].fd = pipefd[0];
807 fds[0].events = POLLIN;
808 // fds[1].fd uninitialized
809 fds[1].events = POLLIN;
810 EXPECT_UMR(poll(fds, 2, 0));
811
812 close(pipefd[0]);
813 close(pipefd[1]);
814}
815
Evgeniy Stepanov9f58c5c2013-05-22 13:46:22 +0000816TEST(MemorySanitizer, bind_getsockname) {
817 int sock = socket(AF_UNIX, SOCK_STREAM, 0);
818
819 struct sockaddr_in sai;
820 memset(&sai, 0, sizeof(sai));
821 sai.sin_family = AF_UNIX;
822 int res = bind(sock, (struct sockaddr *)&sai, sizeof(sai));
823
824 assert(!res);
825 char buf[200];
826 socklen_t addrlen;
827 EXPECT_UMR(getsockname(sock, (struct sockaddr *)&buf, &addrlen));
828
829 addrlen = sizeof(buf);
830 res = getsockname(sock, (struct sockaddr *)&buf, &addrlen);
831 EXPECT_NOT_POISONED(addrlen);
832 EXPECT_NOT_POISONED(buf[0]);
833 EXPECT_NOT_POISONED(buf[addrlen - 1]);
834 EXPECT_POISONED(buf[addrlen]);
835 close(sock);
836}
837
Evgeniy Stepanov9d1525e2013-05-29 09:09:58 +0000838TEST(MemorySanitizer, accept) {
839 int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
840 ASSERT_LT(0, listen_socket);
841
842 struct sockaddr_in sai;
Evgeniy Stepanovab8bf092013-10-17 11:32:30 +0000843 memset(&sai, 0, sizeof(sai));
Evgeniy Stepanov9d1525e2013-05-29 09:09:58 +0000844 sai.sin_family = AF_INET;
845 sai.sin_port = 0;
846 sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
847 int res = bind(listen_socket, (struct sockaddr *)&sai, sizeof(sai));
848 ASSERT_EQ(0, res);
849
850 res = listen(listen_socket, 1);
851 ASSERT_EQ(0, res);
852
853 socklen_t sz = sizeof(sai);
854 res = getsockname(listen_socket, (struct sockaddr *)&sai, &sz);
855 ASSERT_EQ(0, res);
856 ASSERT_EQ(sizeof(sai), sz);
Evgeniy Stepanovbc33e132013-05-29 11:49:25 +0000857
Evgeniy Stepanov9d1525e2013-05-29 09:09:58 +0000858 int connect_socket = socket(AF_INET, SOCK_STREAM, 0);
859 ASSERT_LT(0, connect_socket);
860 res = fcntl(connect_socket, F_SETFL, O_NONBLOCK);
861 ASSERT_EQ(0, res);
862 res = connect(connect_socket, (struct sockaddr *)&sai, sizeof(sai));
863 ASSERT_EQ(-1, res);
864 ASSERT_EQ(EINPROGRESS, errno);
865
866 __msan_poison(&sai, sizeof(sai));
Evgeniy Stepanovbc33e132013-05-29 11:49:25 +0000867 int new_sock = accept(listen_socket, (struct sockaddr *)&sai, &sz);
Evgeniy Stepanov9d1525e2013-05-29 09:09:58 +0000868 ASSERT_LT(0, new_sock);
869 ASSERT_EQ(sizeof(sai), sz);
870 EXPECT_NOT_POISONED(sai);
871
Evgeniy Stepanovbc33e132013-05-29 11:49:25 +0000872 __msan_poison(&sai, sizeof(sai));
873 res = getpeername(new_sock, (struct sockaddr *)&sai, &sz);
874 ASSERT_EQ(0, res);
875 ASSERT_EQ(sizeof(sai), sz);
876 EXPECT_NOT_POISONED(sai);
877
Evgeniy Stepanov9d1525e2013-05-29 09:09:58 +0000878 close(new_sock);
879 close(connect_socket);
880 close(listen_socket);
881}
882
Evgeniy Stepanov512c6162013-05-29 12:33:31 +0000883TEST(MemorySanitizer, getaddrinfo) {
884 struct addrinfo *ai;
885 struct addrinfo hints;
886 memset(&hints, 0, sizeof(hints));
887 hints.ai_family = AF_INET;
888 int res = getaddrinfo("localhost", NULL, &hints, &ai);
889 ASSERT_EQ(0, res);
890 EXPECT_NOT_POISONED(*ai);
891 ASSERT_EQ(sizeof(sockaddr_in), ai->ai_addrlen);
892 EXPECT_NOT_POISONED(*(sockaddr_in*)ai->ai_addr);
893}
894
Evgeniy Stepanov9eedf482013-07-01 13:51:31 +0000895TEST(MemorySanitizer, getnameinfo) {
896 struct sockaddr_in sai;
Evgeniy Stepanovab8bf092013-10-17 11:32:30 +0000897 memset(&sai, 0, sizeof(sai));
Evgeniy Stepanov9eedf482013-07-01 13:51:31 +0000898 sai.sin_family = AF_INET;
899 sai.sin_port = 80;
900 sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
901 char host[500];
902 char serv[500];
903 int res = getnameinfo((struct sockaddr *)&sai, sizeof(sai), host,
904 sizeof(host), serv, sizeof(serv), 0);
905 ASSERT_EQ(0, res);
906 EXPECT_NOT_POISONED(host[0]);
907 EXPECT_POISONED(host[sizeof(host) - 1]);
908
909 ASSERT_NE(0, strlen(host));
910 EXPECT_NOT_POISONED(serv[0]);
911 EXPECT_POISONED(serv[sizeof(serv) - 1]);
912 ASSERT_NE(0, strlen(serv));
913}
914
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +0000915#define EXPECT_HOSTENT_NOT_POISONED(he) \
916 do { \
917 EXPECT_NOT_POISONED(*(he)); \
918 ASSERT_NE((void *) 0, (he)->h_name); \
919 ASSERT_NE((void *) 0, (he)->h_aliases); \
920 ASSERT_NE((void *) 0, (he)->h_addr_list); \
921 EXPECT_NOT_POISONED(strlen((he)->h_name)); \
922 char **p = (he)->h_aliases; \
923 while (*p) { \
924 EXPECT_NOT_POISONED(strlen(*p)); \
925 ++p; \
926 } \
927 char **q = (he)->h_addr_list; \
928 while (*q) { \
929 EXPECT_NOT_POISONED(*q[0]); \
930 ++q; \
931 } \
932 EXPECT_NOT_POISONED(*q); \
933 } while (0)
934
935TEST(MemorySanitizer, gethostent) {
936 struct hostent *he = gethostent();
937 ASSERT_NE((void *)NULL, he);
938 EXPECT_HOSTENT_NOT_POISONED(he);
939}
940
Evgeniy Stepanov263800b2013-06-27 13:21:00 +0000941#ifndef MSAN_TEST_DISABLE_GETHOSTBYNAME
942
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +0000943TEST(MemorySanitizer, gethostbyname) {
944 struct hostent *he = gethostbyname("localhost");
945 ASSERT_NE((void *)NULL, he);
946 EXPECT_HOSTENT_NOT_POISONED(he);
947}
948
Evgeniy Stepanov263800b2013-06-27 13:21:00 +0000949#endif // MSAN_TEST_DISABLE_GETHOSTBYNAME
950
Evgeniy Stepanovab8bf092013-10-17 11:32:30 +0000951TEST(MemorySanitizer, recvmsg) {
952 int server_socket = socket(AF_INET, SOCK_DGRAM, 0);
953 ASSERT_LT(0, server_socket);
954
955 struct sockaddr_in sai;
956 memset(&sai, 0, sizeof(sai));
957 sai.sin_family = AF_INET;
958 sai.sin_port = 0;
959 sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
960 int res = bind(server_socket, (struct sockaddr *)&sai, sizeof(sai));
961 ASSERT_EQ(0, res);
962
963 socklen_t sz = sizeof(sai);
964 res = getsockname(server_socket, (struct sockaddr *)&sai, &sz);
965 ASSERT_EQ(0, res);
966 ASSERT_EQ(sizeof(sai), sz);
967
968
969 int client_socket = socket(AF_INET, SOCK_DGRAM, 0);
970 ASSERT_LT(0, client_socket);
971
972 struct sockaddr_in client_sai;
973 memset(&client_sai, 0, sizeof(client_sai));
974 client_sai.sin_family = AF_INET;
975 client_sai.sin_port = 0;
976 client_sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
977 res = bind(client_socket, (struct sockaddr *)&client_sai, sizeof(client_sai));
978 ASSERT_EQ(0, res);
979
980 sz = sizeof(client_sai);
981 res = getsockname(client_socket, (struct sockaddr *)&client_sai, &sz);
982 ASSERT_EQ(0, res);
983 ASSERT_EQ(sizeof(client_sai), sz);
984
985
986 const char *s = "message text";
987 struct iovec iov;
988 iov.iov_base = (void *)s;
989 iov.iov_len = strlen(s) + 1;
990 struct msghdr msg;
991 memset(&msg, 0, sizeof(msg));
992 msg.msg_name = &sai;
993 msg.msg_namelen = sizeof(sai);
994 msg.msg_iov = &iov;
995 msg.msg_iovlen = 1;
996 res = sendmsg(client_socket, &msg, 0);
997 ASSERT_LT(0, res);
998
999
1000 char buf[1000];
1001 struct iovec recv_iov;
1002 recv_iov.iov_base = (void *)&buf;
1003 recv_iov.iov_len = sizeof(buf);
1004 struct sockaddr_in recv_sai;
1005 struct msghdr recv_msg;
1006 memset(&recv_msg, 0, sizeof(recv_msg));
1007 recv_msg.msg_name = &recv_sai;
1008 recv_msg.msg_namelen = sizeof(recv_sai);
1009 recv_msg.msg_iov = &recv_iov;
1010 recv_msg.msg_iovlen = 1;
1011 res = recvmsg(server_socket, &recv_msg, 0);
1012 ASSERT_LT(0, res);
1013
1014 ASSERT_EQ(sizeof(recv_sai), recv_msg.msg_namelen);
1015 EXPECT_NOT_POISONED(*(struct sockaddr_in *)recv_msg.msg_name);
1016 EXPECT_STREQ(s, buf);
1017
1018 close(server_socket);
1019 close(client_socket);
1020}
1021
Evgeniy Stepanov0a2cc372013-05-23 11:10:23 +00001022TEST(MemorySanitizer, gethostbyname2) {
1023 struct hostent *he = gethostbyname2("localhost", AF_INET);
1024 ASSERT_NE((void *)NULL, he);
1025 EXPECT_HOSTENT_NOT_POISONED(he);
1026}
1027
1028TEST(MemorySanitizer, gethostbyaddr) {
1029 in_addr_t addr = inet_addr("127.0.0.1");
1030 EXPECT_NOT_POISONED(addr);
1031 struct hostent *he = gethostbyaddr(&addr, sizeof(addr), AF_INET);
1032 ASSERT_NE((void *)NULL, he);
1033 EXPECT_HOSTENT_NOT_POISONED(he);
1034}
1035
1036TEST(MemorySanitizer, gethostent_r) {
1037 char buf[2000];
1038 struct hostent he;
1039 struct hostent *result;
1040 int err;
1041 int res = gethostent_r(&he, buf, sizeof(buf), &result, &err);
1042 ASSERT_EQ(0, res);
1043 EXPECT_NOT_POISONED(result);
1044 ASSERT_NE((void *)NULL, result);
1045 EXPECT_HOSTENT_NOT_POISONED(result);
1046 EXPECT_NOT_POISONED(err);
1047}
1048
1049TEST(MemorySanitizer, gethostbyname_r) {
1050 char buf[2000];
1051 struct hostent he;
1052 struct hostent *result;
1053 int err;
1054 int res = gethostbyname_r("localhost", &he, buf, sizeof(buf), &result, &err);
1055 ASSERT_EQ(0, res);
1056 EXPECT_NOT_POISONED(result);
1057 ASSERT_NE((void *)NULL, result);
1058 EXPECT_HOSTENT_NOT_POISONED(result);
1059 EXPECT_NOT_POISONED(err);
1060}
1061
1062TEST(MemorySanitizer, gethostbyname2_r) {
1063 char buf[2000];
1064 struct hostent he;
1065 struct hostent *result;
1066 int err;
1067 int res = gethostbyname2_r("localhost", AF_INET, &he, buf, sizeof(buf),
1068 &result, &err);
1069 ASSERT_EQ(0, res);
1070 EXPECT_NOT_POISONED(result);
1071 ASSERT_NE((void *)NULL, result);
1072 EXPECT_HOSTENT_NOT_POISONED(result);
1073 EXPECT_NOT_POISONED(err);
1074}
1075
1076TEST(MemorySanitizer, gethostbyaddr_r) {
1077 char buf[2000];
1078 struct hostent he;
1079 struct hostent *result;
1080 int err;
1081 in_addr_t addr = inet_addr("127.0.0.1");
1082 EXPECT_NOT_POISONED(addr);
1083 int res = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &he, buf, sizeof(buf),
1084 &result, &err);
1085 ASSERT_EQ(0, res);
1086 EXPECT_NOT_POISONED(result);
1087 ASSERT_NE((void *)NULL, result);
1088 EXPECT_HOSTENT_NOT_POISONED(result);
1089 EXPECT_NOT_POISONED(err);
1090}
1091
Evgeniy Stepanovf32be422013-05-23 11:38:08 +00001092TEST(MemorySanitizer, getsockopt) {
1093 int sock = socket(AF_UNIX, SOCK_STREAM, 0);
1094 struct linger l[2];
1095 socklen_t sz = sizeof(l[0]);
1096 int res = getsockopt(sock, SOL_SOCKET, SO_LINGER, &l[0], &sz);
1097 ASSERT_EQ(0, res);
1098 ASSERT_EQ(sizeof(l[0]), sz);
1099 EXPECT_NOT_POISONED(l[0]);
1100 EXPECT_POISONED(*(char *)(l + 1));
1101}
1102
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001103TEST(MemorySanitizer, getcwd) {
1104 char path[PATH_MAX + 1];
1105 char* res = getcwd(path, sizeof(path));
1106 assert(res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001107 EXPECT_NOT_POISONED(path[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001108}
1109
Evgeniy Stepanov7eed04c2013-02-12 14:36:22 +00001110TEST(MemorySanitizer, getcwd_gnu) {
1111 char* res = getcwd(NULL, 0);
1112 assert(res);
1113 EXPECT_NOT_POISONED(res[0]);
1114 free(res);
1115}
1116
Evgeniy Stepanov80144892013-07-02 13:34:44 +00001117TEST(MemorySanitizer, get_current_dir_name) {
1118 char* res = get_current_dir_name();
1119 assert(res);
1120 EXPECT_NOT_POISONED(res[0]);
1121 free(res);
1122}
1123
Evgeniy Stepanov5ec19bc2013-07-30 12:46:59 +00001124TEST(MemorySanitizer, confstr) {
1125 char buf[3];
1126 size_t res = confstr(_CS_PATH, buf, sizeof(buf));
1127 ASSERT_GT(res, sizeof(buf));
1128 EXPECT_NOT_POISONED(buf[0]);
1129 EXPECT_NOT_POISONED(buf[sizeof(buf) - 1]);
1130
1131 char buf2[1000];
1132 res = confstr(_CS_PATH, buf2, sizeof(buf2));
1133 ASSERT_LT(res, sizeof(buf2));
1134 EXPECT_NOT_POISONED(buf2[0]);
1135 EXPECT_NOT_POISONED(buf2[res - 1]);
1136 EXPECT_POISONED(buf2[res]);
1137 ASSERT_EQ(res, strlen(buf2) + 1);
1138}
1139
Evgeniy Stepanovd97a15a2013-03-14 12:49:23 +00001140TEST(MemorySanitizer, readdir) {
1141 DIR *dir = opendir(".");
1142 struct dirent *d = readdir(dir);
1143 assert(d);
1144 EXPECT_NOT_POISONED(d->d_name[0]);
1145 closedir(dir);
1146}
1147
Evgeniy Stepanovb5cf98f2013-06-26 15:00:53 +00001148TEST(MemorySanitizer, readdir_r) {
1149 DIR *dir = opendir(".");
1150 struct dirent d;
1151 struct dirent *pd;
1152 int res = readdir_r(dir, &d, &pd);
1153 assert(!res);
1154 EXPECT_NOT_POISONED(pd);
1155 EXPECT_NOT_POISONED(d.d_name[0]);
1156 closedir(dir);
1157}
1158
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001159TEST(MemorySanitizer, realpath) {
1160 const char* relpath = ".";
1161 char path[PATH_MAX + 1];
1162 char* res = realpath(relpath, path);
1163 assert(res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001164 EXPECT_NOT_POISONED(path[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001165}
1166
Evgeniy Stepanov12eb79d2013-07-09 09:53:37 +00001167TEST(MemorySanitizer, realpath_null) {
1168 const char* relpath = ".";
1169 char* res = realpath(relpath, NULL);
1170 printf("%d, %s\n", errno, strerror(errno));
1171 assert(res);
1172 EXPECT_NOT_POISONED(res[0]);
1173 free(res);
1174}
1175
1176TEST(MemorySanitizer, canonicalize_file_name) {
1177 const char* relpath = ".";
1178 char* res = canonicalize_file_name(relpath);
1179 assert(res);
1180 EXPECT_NOT_POISONED(res[0]);
1181 free(res);
1182}
1183
Evgeniy Stepanov534e2ba2013-08-01 11:14:14 +00001184extern char **environ;
1185
1186TEST(MemorySanitizer, setenv) {
1187 setenv("AAA", "BBB", 1);
1188 for (char **envp = environ; *envp; ++envp) {
1189 EXPECT_NOT_POISONED(*envp);
1190 EXPECT_NOT_POISONED(*envp[0]);
1191 }
1192}
1193
1194TEST(MemorySanitizer, putenv) {
1195 char s[] = "AAA=BBB";
1196 putenv(s);
1197 for (char **envp = environ; *envp; ++envp) {
1198 EXPECT_NOT_POISONED(*envp);
1199 EXPECT_NOT_POISONED(*envp[0]);
1200 }
1201}
1202
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001203TEST(MemorySanitizer, memcpy) {
1204 char* x = new char[2];
1205 char* y = new char[2];
1206 x[0] = 1;
1207 x[1] = *GetPoisoned<char>();
1208 memcpy(y, x, 2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001209 EXPECT_NOT_POISONED(y[0]);
1210 EXPECT_POISONED(y[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001211}
1212
Evgeniy Stepanov450eee62013-10-24 11:56:03 +00001213void TestUnalignedMemcpy(int left, int right, bool src_is_aligned) {
1214 const int sz = 20;
1215 char *dst = (char *)malloc(sz);
1216 U4 origin = __msan_get_origin(dst);
1217
1218 char *src = (char *)malloc(sz);
1219 memset(src, 0, sz);
1220
1221 memcpy(dst + left, src_is_aligned ? src + left : src, sz - left - right);
1222 for (int i = 0; i < left; ++i)
1223 EXPECT_POISONED_O(dst[i], origin);
1224 for (int i = 0; i < right; ++i)
1225 EXPECT_POISONED_O(dst[sz - i - 1], origin);
1226 EXPECT_NOT_POISONED(dst[left]);
1227 EXPECT_NOT_POISONED(dst[sz - right - 1]);
1228
1229 free(dst);
1230 free(src);
1231}
1232
1233TEST(MemorySanitizer, memcpy_unaligned) {
1234 for (int i = 0; i < 4; ++i) {
1235 for (int j = 0; j < 4; ++j) {
1236 TestUnalignedMemcpy(i, j, true);
1237 TestUnalignedMemcpy(i, j, false);
1238 }
1239 }
1240}
1241
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001242TEST(MemorySanitizer, memmove) {
1243 char* x = new char[2];
1244 char* y = new char[2];
1245 x[0] = 1;
1246 x[1] = *GetPoisoned<char>();
1247 memmove(y, x, 2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001248 EXPECT_NOT_POISONED(y[0]);
1249 EXPECT_POISONED(y[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001250}
1251
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001252TEST(MemorySanitizer, bcopy) {
1253 char* x = new char[2];
1254 char* y = new char[2];
1255 x[0] = 1;
1256 x[1] = *GetPoisoned<char>();
1257 bcopy(x, y, 2);
1258 EXPECT_NOT_POISONED(y[0]);
1259 EXPECT_POISONED(y[1]);
1260}
1261
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001262TEST(MemorySanitizer, strdup) {
Evgeniy Stepanov8aa1ae02013-03-14 11:10:36 +00001263 char buf[4] = "abc";
1264 __msan_poison(buf + 2, sizeof(*buf));
1265 char *x = strdup(buf);
1266 EXPECT_NOT_POISONED(x[0]);
1267 EXPECT_NOT_POISONED(x[1]);
1268 EXPECT_POISONED(x[2]);
1269 EXPECT_NOT_POISONED(x[3]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001270 free(x);
1271}
1272
Evgeniy Stepanov8aa1ae02013-03-14 11:10:36 +00001273TEST(MemorySanitizer, strndup) {
1274 char buf[4] = "abc";
1275 __msan_poison(buf + 2, sizeof(*buf));
1276 char *x = strndup(buf, 3);
1277 EXPECT_NOT_POISONED(x[0]);
1278 EXPECT_NOT_POISONED(x[1]);
1279 EXPECT_POISONED(x[2]);
1280 EXPECT_NOT_POISONED(x[3]);
1281 free(x);
1282}
1283
1284TEST(MemorySanitizer, strndup_short) {
1285 char buf[4] = "abc";
1286 __msan_poison(buf + 1, sizeof(*buf));
1287 __msan_poison(buf + 2, sizeof(*buf));
1288 char *x = strndup(buf, 2);
1289 EXPECT_NOT_POISONED(x[0]);
1290 EXPECT_POISONED(x[1]);
Evgeniy Stepanov1d21bd12013-03-14 11:58:13 +00001291 EXPECT_NOT_POISONED(x[2]);
Evgeniy Stepanov8aa1ae02013-03-14 11:10:36 +00001292 free(x);
1293}
1294
1295
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001296template<class T, int size>
1297void TestOverlapMemmove() {
1298 T *x = new T[size];
1299 assert(size >= 3);
1300 x[2] = 0;
1301 memmove(x, x + 1, (size - 1) * sizeof(T));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001302 EXPECT_NOT_POISONED(x[1]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001303 if (!__msan_has_dynamic_component()) {
1304 // FIXME: under DR we will lose this information
1305 // because accesses in memmove will unpoisin the shadow.
1306 // We need to use our own memove implementation instead of libc's.
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001307 EXPECT_POISONED(x[0]);
1308 EXPECT_POISONED(x[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001309 }
1310 delete [] x;
1311}
1312
1313TEST(MemorySanitizer, overlap_memmove) {
1314 TestOverlapMemmove<U1, 10>();
1315 TestOverlapMemmove<U1, 1000>();
1316 TestOverlapMemmove<U8, 4>();
1317 TestOverlapMemmove<U8, 1000>();
1318}
1319
1320TEST(MemorySanitizer, strcpy) { // NOLINT
1321 char* x = new char[3];
1322 char* y = new char[3];
1323 x[0] = 'a';
1324 x[1] = *GetPoisoned<char>(1, 1);
1325 x[2] = 0;
1326 strcpy(y, x); // NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001327 EXPECT_NOT_POISONED(y[0]);
1328 EXPECT_POISONED(y[1]);
1329 EXPECT_NOT_POISONED(y[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001330}
1331
1332TEST(MemorySanitizer, strncpy) { // NOLINT
1333 char* x = new char[3];
1334 char* y = new char[3];
1335 x[0] = 'a';
1336 x[1] = *GetPoisoned<char>(1, 1);
1337 x[2] = 0;
1338 strncpy(y, x, 2); // NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001339 EXPECT_NOT_POISONED(y[0]);
1340 EXPECT_POISONED(y[1]);
1341 EXPECT_POISONED(y[2]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001342}
1343
Evgeniy Stepanov4bbbe132013-07-01 15:19:37 +00001344TEST(MemorySanitizer, stpcpy) { // NOLINT
1345 char* x = new char[3];
1346 char* y = new char[3];
1347 x[0] = 'a';
1348 x[1] = *GetPoisoned<char>(1, 1);
1349 x[2] = 0;
1350 char *res = stpcpy(y, x); // NOLINT
1351 ASSERT_EQ(res, y + 2);
1352 EXPECT_NOT_POISONED(y[0]);
1353 EXPECT_POISONED(y[1]);
1354 EXPECT_NOT_POISONED(y[2]);
1355}
1356
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001357TEST(MemorySanitizer, strtol) {
1358 char *e;
1359 assert(1 == strtol("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001360 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001361}
1362
1363TEST(MemorySanitizer, strtoll) {
1364 char *e;
1365 assert(1 == strtoll("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001366 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001367}
1368
1369TEST(MemorySanitizer, strtoul) {
1370 char *e;
1371 assert(1 == strtoul("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001372 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001373}
1374
1375TEST(MemorySanitizer, strtoull) {
1376 char *e;
1377 assert(1 == strtoull("1", &e, 10));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001378 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001379}
1380
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001381TEST(MemorySanitizer, strtoimax) {
1382 char *e;
1383 assert(1 == strtoimax("1", &e, 10));
1384 EXPECT_NOT_POISONED((S8) e);
1385}
1386
1387TEST(MemorySanitizer, strtoumax) {
1388 char *e;
1389 assert(1 == strtoumax("1", &e, 10));
1390 EXPECT_NOT_POISONED((S8) e);
1391}
1392
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001393TEST(MemorySanitizer, strtod) {
1394 char *e;
1395 assert(0 != strtod("1.5", &e));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001396 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001397}
1398
Evgeniy Stepanov3f4beff2013-10-14 11:52:40 +00001399#ifdef __GLIBC__
1400extern "C" double __strtod_l(const char *nptr, char **endptr, locale_t loc);
1401TEST(MemorySanitizer, __strtod_l) {
1402 locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
1403 char *e;
1404 assert(0 != __strtod_l("1.5", &e, loc));
1405 EXPECT_NOT_POISONED((S8) e);
1406 freelocale(loc);
1407}
1408#endif // __GLIBC__
1409
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001410TEST(MemorySanitizer, strtof) {
1411 char *e;
1412 assert(0 != strtof("1.5", &e));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001413 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001414}
1415
1416TEST(MemorySanitizer, strtold) {
1417 char *e;
1418 assert(0 != strtold("1.5", &e));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001419 EXPECT_NOT_POISONED((S8) e);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00001420}
1421
Evgeniy Stepanovc87088b2013-05-29 10:03:11 +00001422TEST(MemorySanitizer, modf) {
1423 double x, y;
1424 x = modf(2.1, &y);
1425 EXPECT_NOT_POISONED(y);
1426}
1427
1428TEST(MemorySanitizer, modff) {
1429 float x, y;
1430 x = modff(2.1, &y);
1431 EXPECT_NOT_POISONED(y);
1432}
1433
1434TEST(MemorySanitizer, modfl) {
1435 long double x, y;
1436 x = modfl(2.1, &y);
1437 EXPECT_NOT_POISONED(y);
1438}
1439
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001440TEST(MemorySanitizer, sprintf) { // NOLINT
1441 char buff[10];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001442 break_optimization(buff);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001443 EXPECT_POISONED(buff[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001444 int res = sprintf(buff, "%d", 1234567); // NOLINT
1445 assert(res == 7);
1446 assert(buff[0] == '1');
1447 assert(buff[1] == '2');
1448 assert(buff[2] == '3');
1449 assert(buff[6] == '7');
1450 assert(buff[7] == 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001451 EXPECT_POISONED(buff[8]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001452}
1453
1454TEST(MemorySanitizer, snprintf) {
1455 char buff[10];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001456 break_optimization(buff);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001457 EXPECT_POISONED(buff[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001458 int res = snprintf(buff, sizeof(buff), "%d", 1234567);
1459 assert(res == 7);
1460 assert(buff[0] == '1');
1461 assert(buff[1] == '2');
1462 assert(buff[2] == '3');
1463 assert(buff[6] == '7');
1464 assert(buff[7] == 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001465 EXPECT_POISONED(buff[8]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001466}
1467
1468TEST(MemorySanitizer, swprintf) {
1469 wchar_t buff[10];
1470 assert(sizeof(wchar_t) == 4);
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001471 break_optimization(buff);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001472 EXPECT_POISONED(buff[0]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001473 int res = swprintf(buff, 9, L"%d", 1234567);
1474 assert(res == 7);
1475 assert(buff[0] == '1');
1476 assert(buff[1] == '2');
1477 assert(buff[2] == '3');
1478 assert(buff[6] == '7');
1479 assert(buff[7] == 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001480 EXPECT_POISONED(buff[8]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001481}
1482
Evgeniy Stepanov0797ed42013-06-21 13:32:26 +00001483TEST(MemorySanitizer, asprintf) { // NOLINT
1484 char *pbuf;
1485 EXPECT_POISONED(pbuf);
1486 int res = asprintf(&pbuf, "%d", 1234567); // NOLINT
1487 assert(res == 7);
1488 EXPECT_NOT_POISONED(pbuf);
1489 assert(pbuf[0] == '1');
1490 assert(pbuf[1] == '2');
1491 assert(pbuf[2] == '3');
1492 assert(pbuf[6] == '7');
1493 assert(pbuf[7] == 0);
1494 free(pbuf);
1495}
1496
Alexey Samsonove43d2102013-07-12 11:59:58 +00001497TEST(MemorySanitizer, mbstowcs) {
1498 const char *x = "abc";
1499 wchar_t buff[10];
1500 int res = mbstowcs(buff, x, 2);
1501 EXPECT_EQ(2, res);
1502 EXPECT_EQ(L'a', buff[0]);
1503 EXPECT_EQ(L'b', buff[1]);
1504 EXPECT_POISONED(buff[2]);
1505 res = mbstowcs(buff, x, 10);
1506 EXPECT_EQ(3, res);
1507 EXPECT_NOT_POISONED(buff[3]);
1508}
1509
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001510TEST(MemorySanitizer, wcstombs) {
1511 const wchar_t *x = L"abc";
1512 char buff[10];
1513 int res = wcstombs(buff, x, 4);
1514 EXPECT_EQ(res, 3);
1515 EXPECT_EQ(buff[0], 'a');
1516 EXPECT_EQ(buff[1], 'b');
1517 EXPECT_EQ(buff[2], 'c');
1518}
1519
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001520TEST(MemorySanitizer, wcsrtombs) {
1521 const wchar_t *x = L"abc";
1522 const wchar_t *p = x;
1523 char buff[10];
1524 mbstate_t mbs;
Evgeniy Stepanov57a10952013-07-10 14:17:46 +00001525 memset(&mbs, 0, sizeof(mbs));
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001526 int res = wcsrtombs(buff, &p, 4, &mbs);
1527 EXPECT_EQ(res, 3);
1528 EXPECT_EQ(buff[0], 'a');
1529 EXPECT_EQ(buff[1], 'b');
1530 EXPECT_EQ(buff[2], 'c');
Evgeniy Stepanov9b21ba62013-07-10 14:01:51 +00001531 EXPECT_EQ(buff[3], '\0');
1532 EXPECT_POISONED(buff[4]);
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001533}
1534
1535TEST(MemorySanitizer, wcsnrtombs) {
1536 const wchar_t *x = L"abc";
1537 const wchar_t *p = x;
1538 char buff[10];
1539 mbstate_t mbs;
Evgeniy Stepanov57a10952013-07-10 14:17:46 +00001540 memset(&mbs, 0, sizeof(mbs));
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001541 int res = wcsnrtombs(buff, &p, 2, 4, &mbs);
1542 EXPECT_EQ(res, 2);
1543 EXPECT_EQ(buff[0], 'a');
1544 EXPECT_EQ(buff[1], 'b');
Evgeniy Stepanov9b21ba62013-07-10 14:01:51 +00001545 EXPECT_POISONED(buff[2]);
Evgeniy Stepanovff6c9fb2013-07-04 13:19:41 +00001546}
1547
Evgeniy Stepanov80144892013-07-02 13:34:44 +00001548TEST(MemorySanitizer, mbtowc) {
1549 const char *x = "abc";
1550 wchar_t wx;
1551 int res = mbtowc(&wx, x, 3);
1552 EXPECT_GT(res, 0);
1553 EXPECT_NOT_POISONED(wx);
1554}
1555
1556TEST(MemorySanitizer, mbrtowc) {
1557 const char *x = "abc";
1558 wchar_t wx;
1559 mbstate_t mbs;
1560 memset(&mbs, 0, sizeof(mbs));
1561 int res = mbrtowc(&wx, x, 3, &mbs);
1562 EXPECT_GT(res, 0);
1563 EXPECT_NOT_POISONED(wx);
1564}
1565
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001566TEST(MemorySanitizer, gettimeofday) {
1567 struct timeval tv;
1568 struct timezone tz;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001569 break_optimization(&tv);
1570 break_optimization(&tz);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001571 assert(sizeof(tv) == 16);
1572 assert(sizeof(tz) == 8);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001573 EXPECT_POISONED(tv.tv_sec);
1574 EXPECT_POISONED(tv.tv_usec);
1575 EXPECT_POISONED(tz.tz_minuteswest);
1576 EXPECT_POISONED(tz.tz_dsttime);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001577 assert(0 == gettimeofday(&tv, &tz));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001578 EXPECT_NOT_POISONED(tv.tv_sec);
1579 EXPECT_NOT_POISONED(tv.tv_usec);
1580 EXPECT_NOT_POISONED(tz.tz_minuteswest);
1581 EXPECT_NOT_POISONED(tz.tz_dsttime);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001582}
1583
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +00001584TEST(MemorySanitizer, clock_gettime) {
1585 struct timespec tp;
1586 EXPECT_POISONED(tp.tv_sec);
1587 EXPECT_POISONED(tp.tv_nsec);
1588 assert(0 == clock_gettime(CLOCK_REALTIME, &tp));
1589 EXPECT_NOT_POISONED(tp.tv_sec);
1590 EXPECT_NOT_POISONED(tp.tv_nsec);
1591}
1592
Evgeniy Stepanov7cdae162013-04-23 11:48:31 +00001593TEST(MemorySanitizer, clock_getres) {
1594 struct timespec tp;
1595 EXPECT_POISONED(tp.tv_sec);
1596 EXPECT_POISONED(tp.tv_nsec);
1597 assert(0 == clock_getres(CLOCK_REALTIME, 0));
1598 EXPECT_POISONED(tp.tv_sec);
1599 EXPECT_POISONED(tp.tv_nsec);
1600 assert(0 == clock_getres(CLOCK_REALTIME, &tp));
1601 EXPECT_NOT_POISONED(tp.tv_sec);
1602 EXPECT_NOT_POISONED(tp.tv_nsec);
1603}
1604
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +00001605TEST(MemorySanitizer, getitimer) {
1606 struct itimerval it1, it2;
1607 int res;
1608 EXPECT_POISONED(it1.it_interval.tv_sec);
1609 EXPECT_POISONED(it1.it_interval.tv_usec);
1610 EXPECT_POISONED(it1.it_value.tv_sec);
1611 EXPECT_POISONED(it1.it_value.tv_usec);
1612 res = getitimer(ITIMER_VIRTUAL, &it1);
1613 assert(!res);
1614 EXPECT_NOT_POISONED(it1.it_interval.tv_sec);
1615 EXPECT_NOT_POISONED(it1.it_interval.tv_usec);
1616 EXPECT_NOT_POISONED(it1.it_value.tv_sec);
1617 EXPECT_NOT_POISONED(it1.it_value.tv_usec);
1618
1619 it1.it_interval.tv_sec = it1.it_value.tv_sec = 10000;
1620 it1.it_interval.tv_usec = it1.it_value.tv_usec = 0;
1621
1622 res = setitimer(ITIMER_VIRTUAL, &it1, &it2);
1623 assert(!res);
1624 EXPECT_NOT_POISONED(it2.it_interval.tv_sec);
1625 EXPECT_NOT_POISONED(it2.it_interval.tv_usec);
1626 EXPECT_NOT_POISONED(it2.it_value.tv_sec);
1627 EXPECT_NOT_POISONED(it2.it_value.tv_usec);
1628
1629 // Check that old_value can be 0, and disable the timer.
1630 memset(&it1, 0, sizeof(it1));
1631 res = setitimer(ITIMER_VIRTUAL, &it1, 0);
1632 assert(!res);
1633}
1634
Evgeniy Stepanov39d68ed2013-08-06 09:54:33 +00001635TEST(MemorySanitizer, setitimer_null) {
1636 setitimer(ITIMER_VIRTUAL, 0, 0);
1637 // Not testing the return value, since it the behaviour seems to differ
1638 // between libc implementations and POSIX.
1639 // Should never crash, though.
1640}
1641
Evgeniy Stepanovfef66052013-04-08 08:25:22 +00001642TEST(MemorySanitizer, time) {
1643 time_t t;
1644 EXPECT_POISONED(t);
1645 time_t t2 = time(&t);
1646 assert(t2 != (time_t)-1);
1647 EXPECT_NOT_POISONED(t);
1648}
1649
Evgeniy Stepanov9358c582013-02-19 09:19:16 +00001650TEST(MemorySanitizer, localtime) {
1651 time_t t = 123;
1652 struct tm *time = localtime(&t);
1653 assert(time != 0);
1654 EXPECT_NOT_POISONED(time->tm_sec);
1655 EXPECT_NOT_POISONED(time->tm_hour);
1656 EXPECT_NOT_POISONED(time->tm_year);
1657 EXPECT_NOT_POISONED(time->tm_isdst);
Evgeniy Stepanovcf390322013-10-02 14:30:03 +00001658 EXPECT_NE(0, strlen(time->tm_zone));
Evgeniy Stepanov9358c582013-02-19 09:19:16 +00001659}
1660
1661TEST(MemorySanitizer, localtime_r) {
1662 time_t t = 123;
1663 struct tm time;
1664 struct tm *res = localtime_r(&t, &time);
1665 assert(res != 0);
1666 EXPECT_NOT_POISONED(time.tm_sec);
1667 EXPECT_NOT_POISONED(time.tm_hour);
1668 EXPECT_NOT_POISONED(time.tm_year);
1669 EXPECT_NOT_POISONED(time.tm_isdst);
Evgeniy Stepanovcf390322013-10-02 14:30:03 +00001670 EXPECT_NE(0, strlen(time.tm_zone));
Evgeniy Stepanov9358c582013-02-19 09:19:16 +00001671}
1672
Evgeniy Stepanov4d7297d2013-10-18 09:41:43 +00001673TEST(MemorySanitizer, getmntent) {
1674 FILE *fp = setmntent("/etc/fstab", "r");
1675 struct mntent *mnt = getmntent(fp);
1676 ASSERT_NE((void *)0, mnt);
1677 ASSERT_NE(0, strlen(mnt->mnt_fsname));
1678 ASSERT_NE(0, strlen(mnt->mnt_dir));
1679 ASSERT_NE(0, strlen(mnt->mnt_type));
1680 ASSERT_NE(0, strlen(mnt->mnt_opts));
1681 EXPECT_NOT_POISONED(mnt->mnt_freq);
1682 EXPECT_NOT_POISONED(mnt->mnt_passno);
1683 fclose(fp);
1684}
1685
1686TEST(MemorySanitizer, getmntent_r) {
1687 FILE *fp = setmntent("/etc/fstab", "r");
1688 struct mntent mntbuf;
1689 char buf[1000];
1690 struct mntent *mnt = getmntent_r(fp, &mntbuf, buf, sizeof(buf));
1691 ASSERT_NE((void *)0, mnt);
1692 ASSERT_NE(0, strlen(mnt->mnt_fsname));
1693 ASSERT_NE(0, strlen(mnt->mnt_dir));
1694 ASSERT_NE(0, strlen(mnt->mnt_type));
1695 ASSERT_NE(0, strlen(mnt->mnt_opts));
1696 EXPECT_NOT_POISONED(mnt->mnt_freq);
1697 EXPECT_NOT_POISONED(mnt->mnt_passno);
1698 fclose(fp);
1699}
1700
Evgeniy Stepanov369a9a62013-10-23 13:57:47 +00001701TEST(MemorySanitizer, ether) {
1702 const char *asc = "11:22:33:44:55:66";
1703 struct ether_addr *paddr = ether_aton(asc);
1704 EXPECT_NOT_POISONED(*paddr);
1705
1706 struct ether_addr addr;
1707 paddr = ether_aton_r(asc, &addr);
1708 ASSERT_EQ(paddr, &addr);
1709 EXPECT_NOT_POISONED(addr);
1710
1711 char *s = ether_ntoa(&addr);
1712 ASSERT_NE(0, strlen(s));
1713
1714 char buf[100];
1715 s = ether_ntoa_r(&addr, buf);
1716 ASSERT_EQ(s, buf);
1717 ASSERT_NE(0, strlen(buf));
1718}
1719
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001720TEST(MemorySanitizer, mmap) {
1721 const int size = 4096;
1722 void *p1, *p2;
1723 p1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
1724 __msan_poison(p1, size);
1725 munmap(p1, size);
1726 for (int i = 0; i < 1000; i++) {
1727 p2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
1728 if (p2 == p1)
1729 break;
1730 else
1731 munmap(p2, size);
1732 }
1733 if (p1 == p2) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001734 EXPECT_NOT_POISONED(*(char*)p2);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001735 munmap(p2, size);
1736 }
1737}
1738
1739// FIXME: enable and add ecvt.
1740// FIXME: check why msandr does nt handle fcvt.
1741TEST(MemorySanitizer, fcvt) {
1742 int a, b;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001743 break_optimization(&a);
1744 break_optimization(&b);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001745 EXPECT_POISONED(a);
1746 EXPECT_POISONED(b);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001747 char *str = fcvt(12345.6789, 10, &a, &b);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001748 EXPECT_NOT_POISONED(a);
1749 EXPECT_NOT_POISONED(b);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001750}
1751
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +00001752TEST(MemorySanitizer, frexp) {
1753 int x;
1754 x = *GetPoisoned<int>();
1755 double r = frexp(1.1, &x);
1756 EXPECT_NOT_POISONED(r);
1757 EXPECT_NOT_POISONED(x);
1758
1759 x = *GetPoisoned<int>();
1760 float rf = frexpf(1.1, &x);
1761 EXPECT_NOT_POISONED(rf);
1762 EXPECT_NOT_POISONED(x);
1763
1764 x = *GetPoisoned<int>();
1765 double rl = frexpl(1.1, &x);
1766 EXPECT_NOT_POISONED(rl);
1767 EXPECT_NOT_POISONED(x);
1768}
1769
Evgeniy Stepanov06658ea2013-04-04 08:22:52 +00001770namespace {
1771
1772static int cnt;
1773
1774void SigactionHandler(int signo, siginfo_t* si, void* uc) {
1775 assert(signo == SIGPROF);
1776 assert(si);
1777 EXPECT_NOT_POISONED(si->si_errno);
1778 EXPECT_NOT_POISONED(si->si_pid);
1779#if __linux__
1780# if defined(__x86_64__)
1781 EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_RIP]);
1782# elif defined(__i386__)
1783 EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_EIP]);
1784# endif
1785#endif
1786 ++cnt;
1787}
1788
1789TEST(MemorySanitizer, sigaction) {
1790 struct sigaction act = {};
Evgeniy Stepanovcd3049d2013-04-05 12:58:07 +00001791 struct sigaction oldact = {};
Evgeniy Stepanov6d0b7f62013-04-15 13:35:05 +00001792 struct sigaction origact = {};
1793
1794 sigaction(SIGPROF, 0, &origact);
1795
Evgeniy Stepanov06658ea2013-04-04 08:22:52 +00001796 act.sa_flags |= SA_SIGINFO;
1797 act.sa_sigaction = &SigactionHandler;
1798 sigaction(SIGPROF, &act, 0);
1799
1800 kill(getpid(), SIGPROF);
1801
1802 act.sa_flags &= ~SA_SIGINFO;
1803 act.sa_handler = SIG_DFL;
1804 sigaction(SIGPROF, &act, 0);
1805
1806 act.sa_flags &= ~SA_SIGINFO;
1807 act.sa_handler = SIG_IGN;
Evgeniy Stepanovcd3049d2013-04-05 12:58:07 +00001808 sigaction(SIGPROF, &act, &oldact);
1809 EXPECT_FALSE(oldact.sa_flags & SA_SIGINFO);
1810 EXPECT_EQ(SIG_DFL, oldact.sa_handler);
Evgeniy Stepanov06658ea2013-04-04 08:22:52 +00001811 kill(getpid(), SIGPROF);
1812
1813 act.sa_flags |= SA_SIGINFO;
1814 act.sa_sigaction = &SigactionHandler;
Evgeniy Stepanovcd3049d2013-04-05 12:58:07 +00001815 sigaction(SIGPROF, &act, &oldact);
1816 EXPECT_FALSE(oldact.sa_flags & SA_SIGINFO);
1817 EXPECT_EQ(SIG_IGN, oldact.sa_handler);
Evgeniy Stepanov06658ea2013-04-04 08:22:52 +00001818 kill(getpid(), SIGPROF);
1819
1820 act.sa_flags &= ~SA_SIGINFO;
1821 act.sa_handler = SIG_DFL;
Evgeniy Stepanovcd3049d2013-04-05 12:58:07 +00001822 sigaction(SIGPROF, &act, &oldact);
1823 EXPECT_TRUE(oldact.sa_flags & SA_SIGINFO);
1824 EXPECT_EQ(&SigactionHandler, oldact.sa_sigaction);
Evgeniy Stepanov06658ea2013-04-04 08:22:52 +00001825 EXPECT_EQ(2, cnt);
Evgeniy Stepanov6d0b7f62013-04-15 13:35:05 +00001826
1827 sigaction(SIGPROF, &origact, 0);
Evgeniy Stepanov06658ea2013-04-04 08:22:52 +00001828}
1829
1830} // namespace
1831
Evgeniy Stepanov9a949a82013-09-25 14:47:43 +00001832
1833TEST(MemorySanitizer, sigemptyset) {
1834 sigset_t s;
1835 EXPECT_POISONED(s);
1836 int res = sigemptyset(&s);
1837 ASSERT_EQ(0, res);
1838 EXPECT_NOT_POISONED(s);
1839}
1840
1841TEST(MemorySanitizer, sigfillset) {
1842 sigset_t s;
1843 EXPECT_POISONED(s);
1844 int res = sigfillset(&s);
1845 ASSERT_EQ(0, res);
1846 EXPECT_NOT_POISONED(s);
1847}
1848
1849TEST(MemorySanitizer, sigpending) {
1850 sigset_t s;
1851 EXPECT_POISONED(s);
1852 int res = sigpending(&s);
1853 ASSERT_EQ(0, res);
1854 EXPECT_NOT_POISONED(s);
1855}
1856
1857TEST(MemorySanitizer, sigprocmask) {
1858 sigset_t s;
1859 EXPECT_POISONED(s);
1860 int res = sigprocmask(SIG_BLOCK, 0, &s);
1861 ASSERT_EQ(0, res);
1862 EXPECT_NOT_POISONED(s);
1863}
1864
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001865struct StructWithDtor {
1866 ~StructWithDtor();
1867};
1868
1869NOINLINE StructWithDtor::~StructWithDtor() {
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00001870 break_optimization(0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001871}
1872
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001873TEST(MemorySanitizer, Invoke) {
1874 StructWithDtor s; // Will cause the calls to become invokes.
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001875 EXPECT_NOT_POISONED(0);
1876 EXPECT_POISONED(*GetPoisoned<int>());
1877 EXPECT_NOT_POISONED(0);
1878 EXPECT_POISONED(*GetPoisoned<int>());
1879 EXPECT_POISONED(ReturnPoisoned<S4>());
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001880}
1881
1882TEST(MemorySanitizer, ptrtoint) {
1883 // Test that shadow is propagated through pointer-to-integer conversion.
1884 void* p = (void*)0xABCD;
1885 __msan_poison(((char*)&p) + 1, sizeof(p));
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001886 EXPECT_NOT_POISONED((((uintptr_t)p) & 0xFF) == 0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001887
1888 void* q = (void*)0xABCD;
1889 __msan_poison(&q, sizeof(q) - 1);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00001890 EXPECT_POISONED((((uintptr_t)q) & 0xFF) == 0);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001891}
1892
1893static void vaargsfn2(int guard, ...) {
1894 va_list vl;
1895 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001896 EXPECT_NOT_POISONED(va_arg(vl, int));
1897 EXPECT_NOT_POISONED(va_arg(vl, int));
1898 EXPECT_NOT_POISONED(va_arg(vl, int));
1899 EXPECT_POISONED(va_arg(vl, double));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001900 va_end(vl);
1901}
1902
1903static void vaargsfn(int guard, ...) {
1904 va_list vl;
1905 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001906 EXPECT_NOT_POISONED(va_arg(vl, int));
1907 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001908 // The following call will overwrite __msan_param_tls.
1909 // Checks after it test that arg shadow was somehow saved across the call.
1910 vaargsfn2(1, 2, 3, 4, *GetPoisoned<double>());
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001911 EXPECT_NOT_POISONED(va_arg(vl, int));
1912 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001913 va_end(vl);
1914}
1915
1916TEST(MemorySanitizer, VAArgTest) {
1917 int* x = GetPoisoned<int>();
1918 int* y = GetPoisoned<int>(4);
1919 vaargsfn(1, 13, *x, 42, *y);
1920}
1921
1922static void vaargsfn_many(int guard, ...) {
1923 va_list vl;
1924 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001925 EXPECT_NOT_POISONED(va_arg(vl, int));
1926 EXPECT_POISONED(va_arg(vl, int));
1927 EXPECT_NOT_POISONED(va_arg(vl, int));
1928 EXPECT_NOT_POISONED(va_arg(vl, int));
1929 EXPECT_NOT_POISONED(va_arg(vl, int));
1930 EXPECT_NOT_POISONED(va_arg(vl, int));
1931 EXPECT_NOT_POISONED(va_arg(vl, int));
1932 EXPECT_NOT_POISONED(va_arg(vl, int));
1933 EXPECT_NOT_POISONED(va_arg(vl, int));
1934 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001935 va_end(vl);
1936}
1937
1938TEST(MemorySanitizer, VAArgManyTest) {
1939 int* x = GetPoisoned<int>();
1940 int* y = GetPoisoned<int>(4);
1941 vaargsfn_many(1, 2, *x, 3, 4, 5, 6, 7, 8, 9, *y);
1942}
1943
1944static void vaargsfn_pass2(va_list vl) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001945 EXPECT_NOT_POISONED(va_arg(vl, int));
1946 EXPECT_NOT_POISONED(va_arg(vl, int));
1947 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001948}
1949
1950static void vaargsfn_pass(int guard, ...) {
1951 va_list vl;
1952 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001953 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001954 vaargsfn_pass2(vl);
1955 va_end(vl);
1956}
1957
1958TEST(MemorySanitizer, VAArgPass) {
1959 int* x = GetPoisoned<int>();
1960 int* y = GetPoisoned<int>(4);
1961 vaargsfn_pass(1, *x, 2, 3, *y);
1962}
1963
1964static void vaargsfn_copy2(va_list vl) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001965 EXPECT_NOT_POISONED(va_arg(vl, int));
1966 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001967}
1968
1969static void vaargsfn_copy(int guard, ...) {
1970 va_list vl;
1971 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001972 EXPECT_NOT_POISONED(va_arg(vl, int));
1973 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001974 va_list vl2;
1975 va_copy(vl2, vl);
1976 vaargsfn_copy2(vl2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001977 EXPECT_NOT_POISONED(va_arg(vl, int));
1978 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001979 va_end(vl);
1980}
1981
1982TEST(MemorySanitizer, VAArgCopy) {
1983 int* x = GetPoisoned<int>();
1984 int* y = GetPoisoned<int>(4);
1985 vaargsfn_copy(1, 2, *x, 3, *y);
1986}
1987
1988static void vaargsfn_ptr(int guard, ...) {
1989 va_list vl;
1990 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00001991 EXPECT_NOT_POISONED(va_arg(vl, int*));
1992 EXPECT_POISONED(va_arg(vl, int*));
1993 EXPECT_NOT_POISONED(va_arg(vl, int*));
1994 EXPECT_POISONED(va_arg(vl, double*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00001995 va_end(vl);
1996}
1997
1998TEST(MemorySanitizer, VAArgPtr) {
1999 int** x = GetPoisoned<int*>();
2000 double** y = GetPoisoned<double*>(8);
2001 int z;
2002 vaargsfn_ptr(1, &z, *x, &z, *y);
2003}
2004
2005static void vaargsfn_overflow(int guard, ...) {
2006 va_list vl;
2007 va_start(vl, guard);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002008 EXPECT_NOT_POISONED(va_arg(vl, int));
2009 EXPECT_NOT_POISONED(va_arg(vl, int));
2010 EXPECT_POISONED(va_arg(vl, int));
2011 EXPECT_NOT_POISONED(va_arg(vl, int));
2012 EXPECT_NOT_POISONED(va_arg(vl, int));
2013 EXPECT_NOT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002014
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002015 EXPECT_NOT_POISONED(va_arg(vl, double));
2016 EXPECT_NOT_POISONED(va_arg(vl, double));
2017 EXPECT_NOT_POISONED(va_arg(vl, double));
2018 EXPECT_POISONED(va_arg(vl, double));
2019 EXPECT_NOT_POISONED(va_arg(vl, double));
2020 EXPECT_POISONED(va_arg(vl, int*));
2021 EXPECT_NOT_POISONED(va_arg(vl, double));
2022 EXPECT_NOT_POISONED(va_arg(vl, double));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002023
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002024 EXPECT_POISONED(va_arg(vl, int));
2025 EXPECT_POISONED(va_arg(vl, double));
2026 EXPECT_POISONED(va_arg(vl, int*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002027
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002028 EXPECT_NOT_POISONED(va_arg(vl, int));
2029 EXPECT_NOT_POISONED(va_arg(vl, double));
2030 EXPECT_NOT_POISONED(va_arg(vl, int*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002031
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002032 EXPECT_POISONED(va_arg(vl, int));
2033 EXPECT_POISONED(va_arg(vl, double));
2034 EXPECT_POISONED(va_arg(vl, int*));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002035
2036 va_end(vl);
2037}
2038
2039TEST(MemorySanitizer, VAArgOverflow) {
2040 int* x = GetPoisoned<int>();
2041 double* y = GetPoisoned<double>(8);
2042 int** p = GetPoisoned<int*>(16);
2043 int z;
2044 vaargsfn_overflow(1,
2045 1, 2, *x, 4, 5, 6,
2046 1.1, 2.2, 3.3, *y, 5.5, *p, 7.7, 8.8,
2047 // the following args will overflow for sure
2048 *x, *y, *p,
2049 7, 9.9, &z,
2050 *x, *y, *p);
2051}
2052
2053static void vaargsfn_tlsoverwrite2(int guard, ...) {
2054 va_list vl;
2055 va_start(vl, guard);
Evgeniy Stepanov3c531df2013-08-23 12:13:18 +00002056 for (int i = 0; i < 20; ++i)
2057 EXPECT_NOT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002058 va_end(vl);
2059}
2060
2061static void vaargsfn_tlsoverwrite(int guard, ...) {
2062 // This call will overwrite TLS contents unless it's backed up somewhere.
Evgeniy Stepanov3c531df2013-08-23 12:13:18 +00002063 vaargsfn_tlsoverwrite2(2,
2064 42, 42, 42, 42, 42,
2065 42, 42, 42, 42, 42,
2066 42, 42, 42, 42, 42,
2067 42, 42, 42, 42, 42); // 20x
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002068 va_list vl;
2069 va_start(vl, guard);
Evgeniy Stepanov3c531df2013-08-23 12:13:18 +00002070 for (int i = 0; i < 20; ++i)
2071 EXPECT_POISONED(va_arg(vl, int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002072 va_end(vl);
2073}
2074
2075TEST(MemorySanitizer, VAArgTLSOverwrite) {
2076 int* x = GetPoisoned<int>();
Evgeniy Stepanov3c531df2013-08-23 12:13:18 +00002077 vaargsfn_tlsoverwrite(1,
2078 *x, *x, *x, *x, *x,
2079 *x, *x, *x, *x, *x,
2080 *x, *x, *x, *x, *x,
2081 *x, *x, *x, *x, *x); // 20x
2082
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002083}
2084
2085struct StructByVal {
2086 int a, b, c, d, e, f;
2087};
2088
2089NOINLINE void StructByValTestFunc(struct StructByVal s) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002090 EXPECT_NOT_POISONED(s.a);
2091 EXPECT_POISONED(s.b);
2092 EXPECT_NOT_POISONED(s.c);
2093 EXPECT_POISONED(s.d);
2094 EXPECT_NOT_POISONED(s.e);
2095 EXPECT_POISONED(s.f);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002096}
2097
2098NOINLINE void StructByValTestFunc1(struct StructByVal s) {
2099 StructByValTestFunc(s);
2100}
2101
2102NOINLINE void StructByValTestFunc2(int z, struct StructByVal s) {
2103 StructByValTestFunc(s);
2104}
2105
2106TEST(MemorySanitizer, StructByVal) {
2107 // Large aggregates are passed as "byval" pointer argument in LLVM.
2108 struct StructByVal s;
2109 s.a = 1;
2110 s.b = *GetPoisoned<int>();
2111 s.c = 2;
2112 s.d = *GetPoisoned<int>();
2113 s.e = 3;
2114 s.f = *GetPoisoned<int>();
2115 StructByValTestFunc(s);
2116 StructByValTestFunc1(s);
2117 StructByValTestFunc2(0, s);
2118}
2119
2120
2121#if MSAN_HAS_M128
Evgeniy Stepanovb921bf22013-04-16 14:09:47 +00002122NOINLINE __m128i m128Eq(__m128i *a, __m128i *b) { return _mm_cmpeq_epi16(*a, *b); }
2123NOINLINE __m128i m128Lt(__m128i *a, __m128i *b) { return _mm_cmplt_epi16(*a, *b); }
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002124TEST(MemorySanitizer, m128) {
2125 __m128i a = _mm_set1_epi16(0x1234);
2126 __m128i b = _mm_set1_epi16(0x7890);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002127 EXPECT_NOT_POISONED(m128Eq(&a, &b));
2128 EXPECT_NOT_POISONED(m128Lt(&a, &b));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002129}
2130// FIXME: add more tests for __m128i.
2131#endif // MSAN_HAS_M128
2132
2133// We should not complain when copying this poisoned hole.
2134struct StructWithHole {
2135 U4 a;
2136 // 4-byte hole.
2137 U8 b;
2138};
2139
2140NOINLINE StructWithHole ReturnStructWithHole() {
2141 StructWithHole res;
2142 __msan_poison(&res, sizeof(res));
2143 res.a = 1;
2144 res.b = 2;
2145 return res;
2146}
2147
2148TEST(MemorySanitizer, StructWithHole) {
2149 StructWithHole a = ReturnStructWithHole();
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00002150 break_optimization(&a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002151}
2152
2153template <class T>
2154NOINLINE T ReturnStruct() {
2155 T res;
2156 __msan_poison(&res, sizeof(res));
2157 res.a = 1;
2158 return res;
2159}
2160
2161template <class T>
2162NOINLINE void TestReturnStruct() {
2163 T s1 = ReturnStruct<T>();
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002164 EXPECT_NOT_POISONED(s1.a);
2165 EXPECT_POISONED(s1.b);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002166}
2167
2168struct SSS1 {
2169 int a, b, c;
2170};
2171struct SSS2 {
2172 int b, a, c;
2173};
2174struct SSS3 {
2175 int b, c, a;
2176};
2177struct SSS4 {
2178 int c, b, a;
2179};
2180
2181struct SSS5 {
2182 int a;
2183 float b;
2184};
2185struct SSS6 {
2186 int a;
2187 double b;
2188};
2189struct SSS7 {
2190 S8 b;
2191 int a;
2192};
2193struct SSS8 {
2194 S2 b;
2195 S8 a;
2196};
2197
2198TEST(MemorySanitizer, IntStruct3) {
2199 TestReturnStruct<SSS1>();
2200 TestReturnStruct<SSS2>();
2201 TestReturnStruct<SSS3>();
2202 TestReturnStruct<SSS4>();
2203 TestReturnStruct<SSS5>();
2204 TestReturnStruct<SSS6>();
2205 TestReturnStruct<SSS7>();
2206 TestReturnStruct<SSS8>();
2207}
2208
2209struct LongStruct {
2210 U1 a1, b1;
2211 U2 a2, b2;
2212 U4 a4, b4;
2213 U8 a8, b8;
2214};
2215
2216NOINLINE LongStruct ReturnLongStruct1() {
2217 LongStruct res;
2218 __msan_poison(&res, sizeof(res));
2219 res.a1 = res.a2 = res.a4 = res.a8 = 111;
2220 // leaves b1, .., b8 poisoned.
2221 return res;
2222}
2223
2224NOINLINE LongStruct ReturnLongStruct2() {
2225 LongStruct res;
2226 __msan_poison(&res, sizeof(res));
2227 res.b1 = res.b2 = res.b4 = res.b8 = 111;
2228 // leaves a1, .., a8 poisoned.
2229 return res;
2230}
2231
2232TEST(MemorySanitizer, LongStruct) {
2233 LongStruct s1 = ReturnLongStruct1();
2234 __msan_print_shadow(&s1, sizeof(s1));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002235 EXPECT_NOT_POISONED(s1.a1);
2236 EXPECT_NOT_POISONED(s1.a2);
2237 EXPECT_NOT_POISONED(s1.a4);
2238 EXPECT_NOT_POISONED(s1.a8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002239
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002240 EXPECT_POISONED(s1.b1);
2241 EXPECT_POISONED(s1.b2);
2242 EXPECT_POISONED(s1.b4);
2243 EXPECT_POISONED(s1.b8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002244
2245 LongStruct s2 = ReturnLongStruct2();
2246 __msan_print_shadow(&s2, sizeof(s2));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002247 EXPECT_NOT_POISONED(s2.b1);
2248 EXPECT_NOT_POISONED(s2.b2);
2249 EXPECT_NOT_POISONED(s2.b4);
2250 EXPECT_NOT_POISONED(s2.b8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002251
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002252 EXPECT_POISONED(s2.a1);
2253 EXPECT_POISONED(s2.a2);
2254 EXPECT_POISONED(s2.a4);
2255 EXPECT_POISONED(s2.a8);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002256}
2257
2258TEST(MemorySanitizer, getrlimit) {
2259 struct rlimit limit;
2260 __msan_poison(&limit, sizeof(limit));
2261 int result = getrlimit(RLIMIT_DATA, &limit);
2262 assert(result == 0);
Evgeniy Stepanov2bba4ef2013-05-16 13:00:25 +00002263 EXPECT_NOT_POISONED(limit.rlim_cur);
2264 EXPECT_NOT_POISONED(limit.rlim_max);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002265}
2266
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00002267TEST(MemorySanitizer, getrusage) {
2268 struct rusage usage;
2269 __msan_poison(&usage, sizeof(usage));
2270 int result = getrusage(RUSAGE_SELF, &usage);
2271 assert(result == 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002272 EXPECT_NOT_POISONED(usage.ru_utime.tv_sec);
2273 EXPECT_NOT_POISONED(usage.ru_utime.tv_usec);
2274 EXPECT_NOT_POISONED(usage.ru_stime.tv_sec);
2275 EXPECT_NOT_POISONED(usage.ru_stime.tv_usec);
2276 EXPECT_NOT_POISONED(usage.ru_maxrss);
2277 EXPECT_NOT_POISONED(usage.ru_minflt);
2278 EXPECT_NOT_POISONED(usage.ru_majflt);
2279 EXPECT_NOT_POISONED(usage.ru_inblock);
2280 EXPECT_NOT_POISONED(usage.ru_oublock);
2281 EXPECT_NOT_POISONED(usage.ru_nvcsw);
2282 EXPECT_NOT_POISONED(usage.ru_nivcsw);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00002283}
2284
Evgeniy Stepanov1aad6b52013-05-17 12:51:13 +00002285#ifdef __GLIBC__
Evgeniy Stepanove6c62f22013-05-21 08:56:22 +00002286extern char *program_invocation_name;
Evgeniy Stepanov1aad6b52013-05-17 12:51:13 +00002287#else // __GLIBC__
2288# error "TODO: port this"
2289#endif
2290
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00002291static void dladdr_testfn() {}
2292
2293TEST(MemorySanitizer, dladdr) {
2294 Dl_info info;
2295 __msan_poison(&info, sizeof(info));
2296 int result = dladdr((const void*)dladdr_testfn, &info);
2297 assert(result != 0);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002298 EXPECT_NOT_POISONED((unsigned long)info.dli_fname);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00002299 if (info.dli_fname)
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002300 EXPECT_NOT_POISONED(strlen(info.dli_fname));
2301 EXPECT_NOT_POISONED((unsigned long)info.dli_fbase);
2302 EXPECT_NOT_POISONED((unsigned long)info.dli_sname);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00002303 if (info.dli_sname)
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002304 EXPECT_NOT_POISONED(strlen(info.dli_sname));
2305 EXPECT_NOT_POISONED((unsigned long)info.dli_saddr);
Evgeniy Stepanove03345b2013-01-17 13:42:17 +00002306}
2307
Evgeniy Stepanov08104e62013-08-02 09:09:02 +00002308#ifndef MSAN_TEST_DISABLE_DLOPEN
2309
Evgeniy Stepanov2bba4ef2013-05-16 13:00:25 +00002310static int dl_phdr_callback(struct dl_phdr_info *info, size_t size, void *data) {
2311 (*(int *)data)++;
2312 EXPECT_NOT_POISONED(info->dlpi_addr);
2313 EXPECT_NOT_POISONED(strlen(info->dlpi_name));
2314 EXPECT_NOT_POISONED(info->dlpi_phnum);
2315 for (int i = 0; i < info->dlpi_phnum; ++i)
2316 EXPECT_NOT_POISONED(info->dlpi_phdr[i]);
2317 return 0;
2318}
2319
Evgeniy Stepanov263800b2013-06-27 13:21:00 +00002320// Compute the path to our loadable DSO. We assume it's in the same
2321// directory. Only use string routines that we intercept so far to do this.
2322static int PathToLoadable(char *buf, size_t sz) {
2323 const char *basename = "libmsan_loadable.x86_64.so";
2324 char *argv0 = program_invocation_name;
2325 char *last_slash = strrchr(argv0, '/');
2326 assert(last_slash);
2327 int res =
2328 snprintf(buf, sz, "%.*s/%s", int(last_slash - argv0), argv0, basename);
2329 return res < sz ? 0 : res;
2330}
2331
Evgeniy Stepanov2bba4ef2013-05-16 13:00:25 +00002332TEST(MemorySanitizer, dl_iterate_phdr) {
Evgeniy Stepanov1aad6b52013-05-17 12:51:13 +00002333 char path[4096];
2334 int res = PathToLoadable(path, sizeof(path));
2335 assert(!res);
2336
2337 // Having at least one dlopen'ed library in the process makes this more
2338 // entertaining.
2339 void *lib = dlopen(path, RTLD_LAZY);
2340 ASSERT_NE((void*)0, lib);
2341
Evgeniy Stepanov2bba4ef2013-05-16 13:00:25 +00002342 int count = 0;
2343 int result = dl_iterate_phdr(dl_phdr_callback, &count);
2344 assert(count > 0);
Evgeniy Stepanov1aad6b52013-05-17 12:51:13 +00002345
2346 dlclose(lib);
Evgeniy Stepanov2bba4ef2013-05-16 13:00:25 +00002347}
2348
Reid Kleckner0f92deb2013-03-11 18:07:42 +00002349
2350TEST(MemorySanitizer, dlopen) {
Evgeniy Stepanov1aad6b52013-05-17 12:51:13 +00002351 char path[4096];
2352 int res = PathToLoadable(path, sizeof(path));
2353 assert(!res);
Reid Kleckner0f92deb2013-03-11 18:07:42 +00002354
2355 // We need to clear shadow for globals when doing dlopen. In order to test
2356 // this, we have to poison the shadow for the DSO before we load it. In
2357 // general this is difficult, but the loader tends to reload things in the
2358 // same place, so we open, close, and then reopen. The global should always
2359 // start out clean after dlopen.
2360 for (int i = 0; i < 2; i++) {
2361 void *lib = dlopen(path, RTLD_LAZY);
2362 if (lib == NULL) {
2363 printf("dlerror: %s\n", dlerror());
2364 assert(lib != NULL);
2365 }
2366 void **(*get_dso_global)() = (void **(*)())dlsym(lib, "get_dso_global");
2367 assert(get_dso_global);
2368 void **dso_global = get_dso_global();
2369 EXPECT_NOT_POISONED(*dso_global);
2370 __msan_poison(dso_global, sizeof(*dso_global));
2371 EXPECT_POISONED(*dso_global);
2372 dlclose(lib);
2373 }
Reid Kleckner0f92deb2013-03-11 18:07:42 +00002374}
Evgeniy Stepanov6c503b92013-03-22 11:59:49 +00002375
2376// Regression test for a crash in dlopen() interceptor.
2377TEST(MemorySanitizer, dlopenFailed) {
2378 const char *path = "/libmsan_loadable_does_not_exist.x86_64.so";
2379 void *lib = dlopen(path, RTLD_LAZY);
2380 ASSERT_EQ(0, lib);
2381}
Reid Kleckner0f92deb2013-03-11 18:07:42 +00002382
Evgeniy Stepanov263800b2013-06-27 13:21:00 +00002383#endif // MSAN_TEST_DISABLE_DLOPEN
2384
Evgeniy Stepanov84ba74c2013-08-07 09:10:16 +00002385TEST(MemorySanitizer, sched_getaffinity) {
2386 cpu_set_t mask;
2387 int res = sched_getaffinity(getpid(), sizeof(mask), &mask);
2388 ASSERT_EQ(0, res);
2389 EXPECT_NOT_POISONED(mask);
2390}
2391
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +00002392TEST(MemorySanitizer, scanf) {
2393 const char *input = "42 hello";
2394 int* d = new int;
2395 char* s = new char[7];
2396 int res = sscanf(input, "%d %5s", d, s);
2397 printf("res %d\n", res);
2398 assert(res == 2);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002399 EXPECT_NOT_POISONED(*d);
2400 EXPECT_NOT_POISONED(s[0]);
2401 EXPECT_NOT_POISONED(s[1]);
2402 EXPECT_NOT_POISONED(s[2]);
2403 EXPECT_NOT_POISONED(s[3]);
2404 EXPECT_NOT_POISONED(s[4]);
2405 EXPECT_NOT_POISONED(s[5]);
2406 EXPECT_POISONED(s[6]);
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +00002407 delete s;
2408 delete d;
2409}
2410
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00002411static void *SimpleThread_threadfn(void* data) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002412 return new int;
2413}
2414
2415TEST(MemorySanitizer, SimpleThread) {
2416 pthread_t t;
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00002417 void *p;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002418 int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL);
2419 assert(!res);
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +00002420 EXPECT_NOT_POISONED(t);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002421 res = pthread_join(t, &p);
2422 assert(!res);
Evgeniy Stepanov65670922013-07-30 12:54:34 +00002423 EXPECT_NOT_POISONED(p);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002424 delete (int*)p;
2425}
2426
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00002427static void *SmallStackThread_threadfn(void* data) {
Evgeniy Stepanov10fd3222013-03-13 09:01:40 +00002428 return 0;
2429}
2430
2431TEST(MemorySanitizer, SmallStackThread) {
2432 pthread_attr_t attr;
2433 pthread_t t;
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00002434 void *p;
Evgeniy Stepanov10fd3222013-03-13 09:01:40 +00002435 int res;
2436 res = pthread_attr_init(&attr);
2437 ASSERT_EQ(0, res);
2438 res = pthread_attr_setstacksize(&attr, 64 * 1024);
2439 ASSERT_EQ(0, res);
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00002440 res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);
Evgeniy Stepanov10fd3222013-03-13 09:01:40 +00002441 ASSERT_EQ(0, res);
2442 res = pthread_join(t, &p);
2443 ASSERT_EQ(0, res);
2444 res = pthread_attr_destroy(&attr);
2445 ASSERT_EQ(0, res);
2446}
2447
Evgeniy Stepanovb9bf7002013-03-19 09:30:52 +00002448TEST(MemorySanitizer, PreAllocatedStackThread) {
2449 pthread_attr_t attr;
2450 pthread_t t;
2451 int res;
2452 res = pthread_attr_init(&attr);
2453 ASSERT_EQ(0, res);
2454 void *stack;
2455 const size_t kStackSize = 64 * 1024;
2456 res = posix_memalign(&stack, 4096, kStackSize);
2457 ASSERT_EQ(0, res);
2458 res = pthread_attr_setstack(&attr, stack, kStackSize);
2459 ASSERT_EQ(0, res);
2460 // A small self-allocated stack can not be extended by the tool.
2461 // In this case pthread_create is expected to fail.
2462 res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);
2463 EXPECT_NE(0, res);
2464 res = pthread_attr_destroy(&attr);
2465 ASSERT_EQ(0, res);
2466}
2467
Evgeniy Stepanov56d34722013-05-21 08:12:08 +00002468TEST(MemorySanitizer, pthread_getschedparam) {
2469 int policy;
2470 struct sched_param param;
2471 int res = pthread_getschedparam(pthread_self(), &policy, &param);
2472 ASSERT_EQ(0, res);
2473 EXPECT_NOT_POISONED(policy);
2474 EXPECT_NOT_POISONED(param.sched_priority);
2475}
2476
Evgeniy Stepanov737da2f2013-07-05 12:31:07 +00002477TEST(MemorySanitizer, pthread_key_create) {
2478 pthread_key_t key;
2479 int res = pthread_key_create(&key, NULL);
2480 assert(!res);
2481 EXPECT_NOT_POISONED(key);
2482 res = pthread_key_delete(key);
2483 assert(!res);
2484}
2485
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002486namespace {
2487struct SignalCondArg {
2488 pthread_cond_t* cond;
2489 pthread_mutex_t* mu;
Alexey Samsonovfc813462013-10-17 09:24:03 +00002490 bool broadcast;
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002491};
2492
2493void *SignalCond(void *param) {
2494 SignalCondArg *arg = reinterpret_cast<SignalCondArg *>(param);
2495 pthread_mutex_lock(arg->mu);
Alexey Samsonovfc813462013-10-17 09:24:03 +00002496 if (arg->broadcast)
2497 pthread_cond_broadcast(arg->cond);
2498 else
2499 pthread_cond_signal(arg->cond);
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002500 pthread_mutex_unlock(arg->mu);
2501 return 0;
2502}
2503} // namespace
2504
2505TEST(MemorySanitizer, pthread_cond_wait) {
2506 pthread_cond_t cond;
2507 pthread_mutex_t mu;
Alexey Samsonovfc813462013-10-17 09:24:03 +00002508 SignalCondArg args = {&cond, &mu, false};
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002509 pthread_cond_init(&cond, 0);
2510 pthread_mutex_init(&mu, 0);
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002511 pthread_mutex_lock(&mu);
Alexey Samsonovfc813462013-10-17 09:24:03 +00002512
2513 // signal
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002514 pthread_t thr;
2515 pthread_create(&thr, 0, SignalCond, &args);
2516 int res = pthread_cond_wait(&cond, &mu);
2517 assert(!res);
2518 pthread_join(thr, 0);
Alexey Samsonovfc813462013-10-17 09:24:03 +00002519
2520 // broadcast
2521 args.broadcast = true;
2522 pthread_create(&thr, 0, SignalCond, &args);
2523 res = pthread_cond_wait(&cond, &mu);
2524 assert(!res);
2525 pthread_join(thr, 0);
2526
Alexey Samsonov5e2d3772013-10-16 08:20:31 +00002527 pthread_mutex_unlock(&mu);
2528 pthread_mutex_destroy(&mu);
2529 pthread_cond_destroy(&cond);
2530}
2531
Evgeniy Stepanovb6c8e472013-04-23 13:27:36 +00002532TEST(MemorySanitizer, posix_memalign) {
2533 void *p;
2534 EXPECT_POISONED(p);
2535 int res = posix_memalign(&p, 4096, 13);
2536 ASSERT_EQ(0, res);
2537 EXPECT_NOT_POISONED(p);
Evgeniy Stepanov97160a82013-09-02 09:24:53 +00002538 EXPECT_EQ(0U, (uintptr_t)p % 4096);
2539 free(p);
2540}
2541
2542TEST(MemorySanitizer, memalign) {
2543 void *p = memalign(4096, 13);
2544 EXPECT_EQ(0U, (uintptr_t)p % kPageSize);
2545 free(p);
2546}
2547
2548TEST(MemorySanitizer, valloc) {
2549 void *a = valloc(100);
2550 EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
2551 free(a);
2552}
2553
2554TEST(MemorySanitizer, pvalloc) {
2555 void *p = pvalloc(kPageSize + 100);
2556 EXPECT_EQ(0U, (uintptr_t)p % kPageSize);
2557 EXPECT_EQ(2 * kPageSize, __msan_get_allocated_size(p));
2558 free(p);
2559
2560 p = pvalloc(0); // pvalloc(0) should allocate at least one page.
2561 EXPECT_EQ(0U, (uintptr_t)p % kPageSize);
2562 EXPECT_EQ(kPageSize, __msan_get_allocated_size(p));
Evgeniy Stepanovb6c8e472013-04-23 13:27:36 +00002563 free(p);
2564}
2565
Evgeniy Stepanov9530eb72013-04-23 14:05:15 +00002566TEST(MemorySanitizer, inet_pton) {
2567 const char *s = "1:0:0:0:0:0:0:8";
2568 unsigned char buf[sizeof(struct in6_addr)];
2569 int res = inet_pton(AF_INET6, s, buf);
2570 ASSERT_EQ(1, res);
2571 EXPECT_NOT_POISONED(buf[0]);
2572 EXPECT_NOT_POISONED(buf[sizeof(struct in6_addr) - 1]);
2573
2574 char s_out[INET6_ADDRSTRLEN];
2575 EXPECT_POISONED(s_out[3]);
2576 const char *q = inet_ntop(AF_INET6, buf, s_out, INET6_ADDRSTRLEN);
2577 ASSERT_NE((void*)0, q);
2578 EXPECT_NOT_POISONED(s_out[3]);
2579}
2580
Evgeniy Stepanov9d600872013-06-24 13:56:14 +00002581TEST(MemorySanitizer, inet_aton) {
2582 const char *s = "127.0.0.1";
2583 struct in_addr in[2];
2584 int res = inet_aton(s, in);
2585 ASSERT_NE(0, res);
2586 EXPECT_NOT_POISONED(in[0]);
2587 EXPECT_POISONED(*(char *)(in + 1));
2588}
2589
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002590TEST(MemorySanitizer, uname) {
2591 struct utsname u;
2592 int res = uname(&u);
2593 assert(!res);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002594 EXPECT_NOT_POISONED(strlen(u.sysname));
2595 EXPECT_NOT_POISONED(strlen(u.nodename));
2596 EXPECT_NOT_POISONED(strlen(u.release));
2597 EXPECT_NOT_POISONED(strlen(u.version));
2598 EXPECT_NOT_POISONED(strlen(u.machine));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002599}
2600
Evgeniy Stepanov95d05882013-01-23 10:43:38 +00002601TEST(MemorySanitizer, gethostname) {
2602 char buf[100];
2603 int res = gethostname(buf, 100);
2604 assert(!res);
2605 EXPECT_NOT_POISONED(strlen(buf));
2606}
2607
Evgeniy Stepanov359d7fc2013-06-24 14:25:33 +00002608TEST(MemorySanitizer, sysinfo) {
2609 struct sysinfo info;
2610 int res = sysinfo(&info);
2611 assert(!res);
2612 EXPECT_NOT_POISONED(info);
2613}
2614
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +00002615TEST(MemorySanitizer, getpwuid) {
2616 struct passwd *p = getpwuid(0); // root
2617 assert(p);
2618 EXPECT_NOT_POISONED(p->pw_name);
2619 assert(p->pw_name);
2620 EXPECT_NOT_POISONED(p->pw_name[0]);
2621 EXPECT_NOT_POISONED(p->pw_uid);
2622 assert(p->pw_uid == 0);
2623}
2624
2625TEST(MemorySanitizer, getpwnam_r) {
2626 struct passwd pwd;
2627 struct passwd *pwdres;
2628 char buf[10000];
2629 int res = getpwnam_r("root", &pwd, buf, sizeof(buf), &pwdres);
2630 assert(!res);
2631 EXPECT_NOT_POISONED(pwd.pw_name);
2632 assert(pwd.pw_name);
2633 EXPECT_NOT_POISONED(pwd.pw_name[0]);
2634 EXPECT_NOT_POISONED(pwd.pw_uid);
2635 assert(pwd.pw_uid == 0);
2636}
2637
2638TEST(MemorySanitizer, getpwnam_r_positive) {
2639 struct passwd pwd;
2640 struct passwd *pwdres;
2641 char s[5];
2642 strncpy(s, "abcd", 5);
2643 __msan_poison(s, 5);
2644 char buf[10000];
2645 int res;
2646 EXPECT_UMR(res = getpwnam_r(s, &pwd, buf, sizeof(buf), &pwdres));
2647}
2648
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +00002649TEST(MemorySanitizer, getgrnam_r) {
2650 struct group grp;
2651 struct group *grpres;
2652 char buf[10000];
2653 int res = getgrnam_r("root", &grp, buf, sizeof(buf), &grpres);
2654 assert(!res);
2655 EXPECT_NOT_POISONED(grp.gr_name);
2656 assert(grp.gr_name);
2657 EXPECT_NOT_POISONED(grp.gr_name[0]);
2658 EXPECT_NOT_POISONED(grp.gr_gid);
2659}
2660
Evgeniy Stepanovedff34b2013-08-12 11:01:40 +00002661TEST(MemorySanitizer, getgroups) {
2662 int n = getgroups(0, 0);
2663 gid_t *gids = new gid_t[n];
2664 int res = getgroups(n, gids);
2665 ASSERT_EQ(n, res);
2666 for (int i = 0; i < n; ++i)
2667 EXPECT_NOT_POISONED(gids[i]);
2668}
2669
Evgeniy Stepanovc5a38552013-09-24 14:38:22 +00002670TEST(MemorySanitizer, wordexp) {
2671 wordexp_t w;
2672 int res = wordexp("a b c", &w, 0);
2673 ASSERT_EQ(0, res);
2674 ASSERT_EQ(3, w.we_wordc);
2675 ASSERT_STREQ("a", w.we_wordv[0]);
2676 ASSERT_STREQ("b", w.we_wordv[1]);
2677 ASSERT_STREQ("c", w.we_wordv[2]);
2678}
2679
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002680template<class T>
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002681static bool applySlt(T value, T shadow) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002682 __msan_partial_poison(&value, &shadow, sizeof(T));
2683 volatile bool zzz = true;
2684 // This "|| zzz" trick somehow makes LLVM emit "icmp slt" instead of
2685 // a shift-and-trunc to get at the highest bit.
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002686 volatile bool v = value < 0 || zzz;
2687 return v;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002688}
2689
2690TEST(MemorySanitizer, SignedCompareWithZero) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002691 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xF));
2692 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFF));
2693 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFFFFFF));
2694 EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0x7FFFFFF));
2695 EXPECT_UMR(applySlt<S4>(0xF, 0x80FFFFFF));
2696 EXPECT_UMR(applySlt<S4>(0xF, 0xFFFFFFFF));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002697}
2698
Evgeniy Stepanov9a22a3d2013-01-25 15:39:11 +00002699template <class T, class S>
2700static T poisoned(T Va, S Sa) {
2701 char SIZE_CHECK1[(ssize_t)sizeof(T) - (ssize_t)sizeof(S)];
2702 char SIZE_CHECK2[(ssize_t)sizeof(S) - (ssize_t)sizeof(T)];
2703 T a;
2704 a = Va;
2705 __msan_partial_poison(&a, &Sa, sizeof(T));
2706 return a;
2707}
2708
2709TEST(MemorySanitizer, ICmpRelational) {
2710 EXPECT_NOT_POISONED(poisoned(0, 0) < poisoned(0, 0));
2711 EXPECT_NOT_POISONED(poisoned(0U, 0) < poisoned(0U, 0));
2712 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) < poisoned(0LL, 0LLU));
2713 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) < poisoned(0LLU, 0LLU));
2714 EXPECT_POISONED(poisoned(0xFF, 0xFF) < poisoned(0xFF, 0xFF));
2715 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <
2716 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
2717 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <
2718 poisoned(-1, 0xFFFFFFFFU));
2719
2720 EXPECT_NOT_POISONED(poisoned(0, 0) <= poisoned(0, 0));
2721 EXPECT_NOT_POISONED(poisoned(0U, 0) <= poisoned(0U, 0));
2722 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) <= poisoned(0LL, 0LLU));
2723 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) <= poisoned(0LLU, 0LLU));
2724 EXPECT_POISONED(poisoned(0xFF, 0xFF) <= poisoned(0xFF, 0xFF));
2725 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <=
2726 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
2727 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <=
2728 poisoned(-1, 0xFFFFFFFFU));
2729
2730 EXPECT_NOT_POISONED(poisoned(0, 0) > poisoned(0, 0));
2731 EXPECT_NOT_POISONED(poisoned(0U, 0) > poisoned(0U, 0));
2732 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) > poisoned(0LL, 0LLU));
2733 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) > poisoned(0LLU, 0LLU));
2734 EXPECT_POISONED(poisoned(0xFF, 0xFF) > poisoned(0xFF, 0xFF));
2735 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >
2736 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
2737 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >
2738 poisoned(-1, 0xFFFFFFFFU));
2739
2740 EXPECT_NOT_POISONED(poisoned(0, 0) >= poisoned(0, 0));
2741 EXPECT_NOT_POISONED(poisoned(0U, 0) >= poisoned(0U, 0));
2742 EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) >= poisoned(0LL, 0LLU));
2743 EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) >= poisoned(0LLU, 0LLU));
2744 EXPECT_POISONED(poisoned(0xFF, 0xFF) >= poisoned(0xFF, 0xFF));
2745 EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >=
2746 poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
2747 EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >=
2748 poisoned(-1, 0xFFFFFFFFU));
2749
Evgeniy Stepanov9a22a3d2013-01-25 15:39:11 +00002750 EXPECT_POISONED(poisoned(6, 0xF) > poisoned(7, 0));
2751 EXPECT_POISONED(poisoned(0xF, 0xF) > poisoned(7, 0));
2752
2753 EXPECT_NOT_POISONED(poisoned(-1, 0x80000000U) >= poisoned(-1, 0U));
Evgeniy Stepanov9a22a3d2013-01-25 15:39:11 +00002754}
2755
2756#if MSAN_HAS_M128
2757TEST(MemorySanitizer, ICmpVectorRelational) {
Evgeniy Stepanovb921bf22013-04-16 14:09:47 +00002758 EXPECT_NOT_POISONED(
2759 _mm_cmplt_epi16(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0)),
2760 poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0))));
2761 EXPECT_NOT_POISONED(
2762 _mm_cmplt_epi16(poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0)),
2763 poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0))));
2764 EXPECT_POISONED(
2765 _mm_cmplt_epi16(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF)),
2766 poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF))));
2767 EXPECT_POISONED(_mm_cmpgt_epi16(poisoned(_mm_set1_epi16(6), _mm_set1_epi16(0xF)),
2768 poisoned(_mm_set1_epi16(7), _mm_set1_epi16(0))));
Evgeniy Stepanov9a22a3d2013-01-25 15:39:11 +00002769}
2770#endif
2771
Evgeniy Stepanov2efa1422013-01-22 12:31:39 +00002772// Volatile bitfield store is implemented as load-mask-store
2773// Test that we don't warn on the store of (uninitialized) padding.
2774struct VolatileBitfieldStruct {
2775 volatile unsigned x : 1;
2776 unsigned y : 1;
2777};
2778
2779TEST(MemorySanitizer, VolatileBitfield) {
2780 VolatileBitfieldStruct *S = new VolatileBitfieldStruct;
2781 S->x = 1;
Evgeniy Stepanov02f4a942013-01-22 12:33:11 +00002782 EXPECT_NOT_POISONED((unsigned)S->x);
2783 EXPECT_POISONED((unsigned)S->y);
Evgeniy Stepanov2efa1422013-01-22 12:31:39 +00002784}
2785
Evgeniy Stepanovf43f6022013-06-04 13:08:36 +00002786TEST(MemorySanitizer, UnalignedLoad) {
2787 char x[32];
2788 memset(x + 8, 0, 16);
2789 EXPECT_POISONED(__sanitizer_unaligned_load16(x+6));
2790 EXPECT_POISONED(__sanitizer_unaligned_load16(x+7));
2791 EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+8));
2792 EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+9));
2793 EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+22));
2794 EXPECT_POISONED(__sanitizer_unaligned_load16(x+23));
2795 EXPECT_POISONED(__sanitizer_unaligned_load16(x+24));
2796
2797 EXPECT_POISONED(__sanitizer_unaligned_load32(x+4));
2798 EXPECT_POISONED(__sanitizer_unaligned_load32(x+7));
2799 EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+8));
2800 EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+9));
2801 EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+20));
2802 EXPECT_POISONED(__sanitizer_unaligned_load32(x+21));
2803 EXPECT_POISONED(__sanitizer_unaligned_load32(x+24));
2804
2805 EXPECT_POISONED(__sanitizer_unaligned_load64(x));
2806 EXPECT_POISONED(__sanitizer_unaligned_load64(x+1));
2807 EXPECT_POISONED(__sanitizer_unaligned_load64(x+7));
2808 EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+8));
2809 EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+9));
2810 EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+16));
2811 EXPECT_POISONED(__sanitizer_unaligned_load64(x+17));
2812 EXPECT_POISONED(__sanitizer_unaligned_load64(x+21));
2813 EXPECT_POISONED(__sanitizer_unaligned_load64(x+24));
2814}
2815
2816TEST(MemorySanitizer, UnalignedStore16) {
2817 char x[5];
2818 U2 y = 0;
2819 __msan_poison(&y, 1);
2820 __sanitizer_unaligned_store16(x + 1, y);
2821 EXPECT_POISONED(x[0]);
2822 EXPECT_POISONED(x[1]);
2823 EXPECT_NOT_POISONED(x[2]);
2824 EXPECT_POISONED(x[3]);
2825 EXPECT_POISONED(x[4]);
2826}
2827
2828TEST(MemorySanitizer, UnalignedStore32) {
2829 char x[8];
2830 U4 y4 = 0;
2831 __msan_poison(&y4, 2);
2832 __sanitizer_unaligned_store32(x+3, y4);
2833 EXPECT_POISONED(x[0]);
2834 EXPECT_POISONED(x[1]);
2835 EXPECT_POISONED(x[2]);
2836 EXPECT_POISONED(x[3]);
2837 EXPECT_POISONED(x[4]);
2838 EXPECT_NOT_POISONED(x[5]);
2839 EXPECT_NOT_POISONED(x[6]);
2840 EXPECT_POISONED(x[7]);
2841}
2842
2843TEST(MemorySanitizer, UnalignedStore64) {
2844 char x[16];
2845 U8 y = 0;
2846 __msan_poison(&y, 3);
2847 __msan_poison(((char *)&y) + sizeof(y) - 2, 1);
2848 __sanitizer_unaligned_store64(x+3, y);
2849 EXPECT_POISONED(x[0]);
2850 EXPECT_POISONED(x[1]);
2851 EXPECT_POISONED(x[2]);
2852 EXPECT_POISONED(x[3]);
2853 EXPECT_POISONED(x[4]);
2854 EXPECT_POISONED(x[5]);
2855 EXPECT_NOT_POISONED(x[6]);
2856 EXPECT_NOT_POISONED(x[7]);
2857 EXPECT_NOT_POISONED(x[8]);
2858 EXPECT_POISONED(x[9]);
2859 EXPECT_NOT_POISONED(x[10]);
2860 EXPECT_POISONED(x[11]);
2861}
2862
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002863TEST(MemorySanitizerDr, StoreInDSOTest) {
2864 if (!__msan_has_dynamic_component()) return;
2865 char* s = new char[10];
2866 dso_memfill(s, 9);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002867 EXPECT_NOT_POISONED(s[5]);
2868 EXPECT_POISONED(s[9]);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002869}
2870
2871int return_poisoned_int() {
2872 return ReturnPoisoned<U8>();
2873}
2874
2875TEST(MemorySanitizerDr, ReturnFromDSOTest) {
2876 if (!__msan_has_dynamic_component()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002877 EXPECT_NOT_POISONED(dso_callfn(return_poisoned_int));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002878}
2879
2880NOINLINE int TrashParamTLS(long long x, long long y, long long z) { //NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002881 EXPECT_POISONED(x);
2882 EXPECT_POISONED(y);
2883 EXPECT_POISONED(z);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002884 return 0;
2885}
2886
2887static int CheckParamTLS(long long x, long long y, long long z) { //NOLINT
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002888 EXPECT_NOT_POISONED(x);
2889 EXPECT_NOT_POISONED(y);
2890 EXPECT_NOT_POISONED(z);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002891 return 0;
2892}
2893
2894TEST(MemorySanitizerDr, CallFromDSOTest) {
2895 if (!__msan_has_dynamic_component()) return;
2896 S8* x = GetPoisoned<S8>();
2897 S8* y = GetPoisoned<S8>();
2898 S8* z = GetPoisoned<S8>();
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002899 EXPECT_NOT_POISONED(TrashParamTLS(*x, *y, *z));
2900 EXPECT_NOT_POISONED(dso_callfn1(CheckParamTLS));
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002901}
2902
2903static void StackStoreInDSOFn(int* x, int* y) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002904 EXPECT_NOT_POISONED(*x);
2905 EXPECT_NOT_POISONED(*y);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002906}
2907
2908TEST(MemorySanitizerDr, StackStoreInDSOTest) {
2909 if (!__msan_has_dynamic_component()) return;
2910 dso_stack_store(StackStoreInDSOFn, 1);
2911}
2912
2913TEST(MemorySanitizerOrigins, SetGet) {
2914 EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins());
2915 if (!TrackingOrigins()) return;
2916 int x;
2917 __msan_set_origin(&x, sizeof(x), 1234);
2918 EXPECT_EQ(1234, __msan_get_origin(&x));
2919 __msan_set_origin(&x, sizeof(x), 5678);
2920 EXPECT_EQ(5678, __msan_get_origin(&x));
2921 __msan_set_origin(&x, sizeof(x), 0);
2922 EXPECT_EQ(0, __msan_get_origin(&x));
2923}
2924
2925namespace {
2926struct S {
2927 U4 dummy;
2928 U2 a;
2929 U2 b;
2930};
2931
2932// http://code.google.com/p/memory-sanitizer/issues/detail?id=6
2933TEST(MemorySanitizerOrigins, DISABLED_InitializedStoreDoesNotChangeOrigin) {
2934 if (!TrackingOrigins()) return;
2935
2936 S s;
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002937 U4 origin = rand(); // NOLINT
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002938 s.a = *GetPoisonedO<U2>(0, origin);
2939 EXPECT_EQ(origin, __msan_get_origin(&s.a));
2940 EXPECT_EQ(origin, __msan_get_origin(&s.b));
2941
2942 s.b = 42;
2943 EXPECT_EQ(origin, __msan_get_origin(&s.a));
2944 EXPECT_EQ(origin, __msan_get_origin(&s.b));
2945}
2946} // namespace
2947
2948template<class T, class BinaryOp>
2949INLINE
2950void BinaryOpOriginTest(BinaryOp op) {
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002951 U4 ox = rand(); //NOLINT
2952 U4 oy = rand(); //NOLINT
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002953 T *x = GetPoisonedO<T>(0, ox, 0);
2954 T *y = GetPoisonedO<T>(1, oy, 0);
2955 T *z = GetPoisonedO<T>(2, 0, 0);
2956
2957 *z = op(*x, *y);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00002958 U4 origin = __msan_get_origin(z);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002959 EXPECT_POISONED_O(*z, origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002960 EXPECT_EQ(true, origin == ox || origin == oy);
2961
2962 // y is poisoned, x is not.
2963 *x = 10101;
2964 *y = *GetPoisonedO<T>(1, oy);
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00002965 break_optimization(x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002966 __msan_set_origin(z, sizeof(*z), 0);
2967 *z = op(*x, *y);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002968 EXPECT_POISONED_O(*z, oy);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002969 EXPECT_EQ(__msan_get_origin(z), oy);
2970
2971 // x is poisoned, y is not.
2972 *x = *GetPoisonedO<T>(0, ox);
2973 *y = 10101010;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00002974 break_optimization(y);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002975 __msan_set_origin(z, sizeof(*z), 0);
2976 *z = op(*x, *y);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00002977 EXPECT_POISONED_O(*z, ox);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00002978 EXPECT_EQ(__msan_get_origin(z), ox);
2979}
2980
2981template<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; }
2982template<class T> INLINE T ADD(const T &a, const T&b) { return a + b; }
2983template<class T> INLINE T SUB(const T &a, const T&b) { return a - b; }
2984template<class T> INLINE T MUL(const T &a, const T&b) { return a * b; }
2985template<class T> INLINE T AND(const T &a, const T&b) { return a & b; }
2986template<class T> INLINE T OR (const T &a, const T&b) { return a | b; }
2987
2988TEST(MemorySanitizerOrigins, BinaryOp) {
2989 if (!TrackingOrigins()) return;
2990 BinaryOpOriginTest<S8>(XOR<S8>);
2991 BinaryOpOriginTest<U8>(ADD<U8>);
2992 BinaryOpOriginTest<S4>(SUB<S4>);
2993 BinaryOpOriginTest<S4>(MUL<S4>);
2994 BinaryOpOriginTest<U4>(OR<U4>);
2995 BinaryOpOriginTest<U4>(AND<U4>);
2996 BinaryOpOriginTest<double>(ADD<U4>);
2997 BinaryOpOriginTest<float>(ADD<S4>);
2998 BinaryOpOriginTest<double>(ADD<double>);
2999 BinaryOpOriginTest<float>(ADD<double>);
3000}
3001
3002TEST(MemorySanitizerOrigins, Unary) {
3003 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003004 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
3005 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
3006 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
3007 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003008
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003009 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
3010 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
3011 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
3012 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003013
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003014 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
3015 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
3016 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
3017 EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003018
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003019 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
3020 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
3021 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
3022 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003023
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003024 EXPECT_POISONED_O((void*)*GetPoisonedO<S8>(0, __LINE__), __LINE__);
3025 EXPECT_POISONED_O((U8)*GetPoisonedO<void*>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003026}
3027
3028TEST(MemorySanitizerOrigins, EQ) {
3029 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003030 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) <= 11, __LINE__);
3031 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) == 11, __LINE__);
3032 EXPECT_POISONED_O(*GetPoisonedO<float>(0, __LINE__) == 1.1, __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003033}
3034
3035TEST(MemorySanitizerOrigins, DIV) {
3036 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003037 EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) / 100, __LINE__);
3038 unsigned o = __LINE__;
3039 EXPECT_UMR_O(volatile unsigned y = 100 / *GetPoisonedO<S4>(0, o, 1), o);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003040}
3041
3042TEST(MemorySanitizerOrigins, SHIFT) {
3043 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003044 EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) >> 10, __LINE__);
3045 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) >> 10, __LINE__);
3046 EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) << 10, __LINE__);
3047 EXPECT_POISONED_O(10U << *GetPoisonedO<U8>(0, __LINE__), __LINE__);
3048 EXPECT_POISONED_O(-10 >> *GetPoisonedO<S8>(0, __LINE__), __LINE__);
3049 EXPECT_POISONED_O(-10 << *GetPoisonedO<S8>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003050}
3051
3052template<class T, int N>
3053void MemCpyTest() {
3054 int ox = __LINE__;
3055 T *x = new T[N];
3056 T *y = new T[N];
3057 T *z = new T[N];
Evgeniy Stepanov353c9962013-07-02 14:49:24 +00003058 T *q = new T[N];
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003059 __msan_poison(x, N * sizeof(T));
3060 __msan_set_origin(x, N * sizeof(T), ox);
3061 __msan_set_origin(y, N * sizeof(T), 777777);
3062 __msan_set_origin(z, N * sizeof(T), 888888);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003063 EXPECT_NOT_POISONED(x);
3064 memcpy(y, x, N * sizeof(T));
3065 EXPECT_POISONED_O(y[0], ox);
3066 EXPECT_POISONED_O(y[N/2], ox);
3067 EXPECT_POISONED_O(y[N-1], ox);
3068 EXPECT_NOT_POISONED(x);
Evgeniy Stepanov353c9962013-07-02 14:49:24 +00003069 void *res = mempcpy(q, x, N * sizeof(T));
3070 ASSERT_EQ(q + N, res);
3071 EXPECT_POISONED_O(q[0], ox);
3072 EXPECT_POISONED_O(q[N/2], ox);
3073 EXPECT_POISONED_O(q[N-1], ox);
3074 EXPECT_NOT_POISONED(x);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003075 memmove(z, x, N * sizeof(T));
3076 EXPECT_POISONED_O(z[0], ox);
3077 EXPECT_POISONED_O(z[N/2], ox);
3078 EXPECT_POISONED_O(z[N-1], ox);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003079}
3080
3081TEST(MemorySanitizerOrigins, LargeMemCpy) {
3082 if (!TrackingOrigins()) return;
3083 MemCpyTest<U1, 10000>();
3084 MemCpyTest<U8, 10000>();
3085}
3086
3087TEST(MemorySanitizerOrigins, SmallMemCpy) {
3088 if (!TrackingOrigins()) return;
3089 MemCpyTest<U8, 1>();
3090 MemCpyTest<U8, 2>();
3091 MemCpyTest<U8, 3>();
3092}
3093
3094TEST(MemorySanitizerOrigins, Select) {
3095 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003096 EXPECT_NOT_POISONED(g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__));
3097 EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003098 S4 x;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00003099 break_optimization(&x);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003100 x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;
3101
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003102 EXPECT_POISONED_O(g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);
3103 EXPECT_POISONED_O(g_0 ? 1 : *GetPoisonedO<S4>(0, __LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003104}
3105
3106extern "C"
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003107NOINLINE char AllocaTO() {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003108 int ar[100];
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00003109 break_optimization(ar);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003110 return ar[10];
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003111 // fprintf(stderr, "Descr: %s\n",
3112 // __msan_get_origin_descr_if_stack(__msan_get_origin_tls()));
3113}
3114
3115TEST(MemorySanitizerOrigins, Alloca) {
3116 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003117 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
3118 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
3119 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
3120 EXPECT_POISONED_S(AllocaTO(), "ar@AllocaTO");
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003121}
3122
3123// FIXME: replace with a lit-like test.
3124TEST(MemorySanitizerOrigins, DISABLED_AllocaDeath) {
3125 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003126 EXPECT_DEATH(AllocaTO(), "ORIGIN: stack allocation: ar@AllocaTO");
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003127}
3128
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00003129NOINLINE int RetvalOriginTest(U4 origin) {
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003130 int *a = new int;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00003131 break_optimization(a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003132 __msan_set_origin(a, sizeof(*a), origin);
3133 int res = *a;
3134 delete a;
3135 return res;
3136}
3137
3138TEST(MemorySanitizerOrigins, Retval) {
3139 if (!TrackingOrigins()) return;
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003140 EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003141}
3142
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00003143NOINLINE void ParamOriginTest(int param, U4 origin) {
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003144 EXPECT_POISONED_O(param, origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003145}
3146
3147TEST(MemorySanitizerOrigins, Param) {
3148 if (!TrackingOrigins()) return;
3149 int *a = new int;
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00003150 U4 origin = __LINE__;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00003151 break_optimization(a);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003152 __msan_set_origin(a, sizeof(*a), origin);
3153 ParamOriginTest(*a, origin);
3154 delete a;
3155}
3156
3157TEST(MemorySanitizerOrigins, Invoke) {
3158 if (!TrackingOrigins()) return;
3159 StructWithDtor s; // Will cause the calls to become invokes.
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003160 EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003161}
3162
3163TEST(MemorySanitizerOrigins, strlen) {
3164 S8 alignment;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00003165 break_optimization(&alignment);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003166 char x[4] = {'a', 'b', 0, 0};
3167 __msan_poison(&x[2], 1);
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00003168 U4 origin = __LINE__;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003169 __msan_set_origin(x, sizeof(x), origin);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003170 EXPECT_UMR_O(volatile unsigned y = strlen(x), origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003171}
3172
3173TEST(MemorySanitizerOrigins, wcslen) {
3174 wchar_t w[3] = {'a', 'b', 0};
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00003175 U4 origin = __LINE__;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003176 __msan_set_origin(w, sizeof(w), origin);
3177 __msan_poison(&w[2], sizeof(wchar_t));
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003178 EXPECT_UMR_O(volatile unsigned y = wcslen(w), origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003179}
3180
3181#if MSAN_HAS_M128
3182TEST(MemorySanitizerOrigins, StoreIntrinsic) {
3183 __m128 x, y;
Evgeniy Stepanov250f2212013-01-30 13:12:08 +00003184 U4 origin = __LINE__;
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003185 __msan_set_origin(&x, sizeof(x), origin);
3186 __msan_poison(&x, sizeof(x));
3187 __builtin_ia32_storeups((float*)&y, x);
Evgeniy Stepanov11929002013-01-22 12:29:00 +00003188 EXPECT_POISONED_O(y, origin);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003189}
3190#endif
3191
3192NOINLINE void RecursiveMalloc(int depth) {
3193 static int count;
3194 count++;
3195 if ((count % (1024 * 1024)) == 0)
3196 printf("RecursiveMalloc: %d\n", count);
3197 int *x1 = new int;
3198 int *x2 = new int;
Evgeniy Stepanov12c46932013-01-29 14:33:29 +00003199 break_optimization(x1);
3200 break_optimization(x2);
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003201 if (depth > 0) {
3202 RecursiveMalloc(depth-1);
3203 RecursiveMalloc(depth-1);
3204 }
3205 delete x1;
3206 delete x2;
3207}
3208
Evgeniy Stepanov20406042013-09-03 10:05:45 +00003209TEST(MemorySanitizer, Select) {
3210 int x;
3211 int volatile* p = &x;
3212 int z = *p ? 1 : 0;
3213 EXPECT_POISONED(z);
3214}
3215
Evgeniy Stepanov0231c502012-12-25 12:39:56 +00003216TEST(MemorySanitizerStress, DISABLED_MallocStackTrace) {
3217 RecursiveMalloc(22);
3218}
Evgeniy Stepanov5c48a8c2013-08-02 14:26:58 +00003219
3220TEST(MemorySanitizerAllocator, get_estimated_allocated_size) {
3221 size_t sizes[] = {0, 20, 5000, 1<<20};
3222 for (size_t i = 0; i < sizeof(sizes) / sizeof(*sizes); ++i) {
3223 size_t alloc_size = __msan_get_estimated_allocated_size(sizes[i]);
3224 EXPECT_EQ(alloc_size, sizes[i]);
3225 }
3226}
3227
3228TEST(MemorySanitizerAllocator, get_allocated_size_and_ownership) {
3229 char *array = reinterpret_cast<char*>(malloc(100));
3230 int *int_ptr = new int;
3231
3232 EXPECT_TRUE(__msan_get_ownership(array));
3233 EXPECT_EQ(100, __msan_get_allocated_size(array));
3234
3235 EXPECT_TRUE(__msan_get_ownership(int_ptr));
3236 EXPECT_EQ(sizeof(*int_ptr), __msan_get_allocated_size(int_ptr));
3237
3238 void *wild_addr = reinterpret_cast<void*>(0x1);
3239 EXPECT_FALSE(__msan_get_ownership(wild_addr));
3240 EXPECT_EQ(0, __msan_get_allocated_size(wild_addr));
3241
3242 EXPECT_FALSE(__msan_get_ownership(array + 50));
3243 EXPECT_EQ(0, __msan_get_allocated_size(array + 50));
3244
3245 // NULL is a valid argument for GetAllocatedSize but is not owned.
3246 EXPECT_FALSE(__msan_get_ownership(NULL));
3247 EXPECT_EQ(0, __msan_get_allocated_size(NULL));
3248
3249 free(array);
3250 EXPECT_FALSE(__msan_get_ownership(array));
3251 EXPECT_EQ(0, __msan_get_allocated_size(array));
3252
3253 delete int_ptr;
3254}