sanitizer_libc_test.cc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
1341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//===-- sanitizer_libc_test.cc --------------------------------------------===//
2341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//
3341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//                     The LLVM Compiler Infrastructure
4341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//
5341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// This file is distributed under the University of Illinois Open Source
6341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// License. See LICENSE.TXT for details.
7341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//
8341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//===----------------------------------------------------------------------===//
9341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// Tests for sanitizer_libc.h.
10341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//===----------------------------------------------------------------------===//
11341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko
124c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#include "sanitizer_common/sanitizer_common.h"
13341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko#include "sanitizer_common/sanitizer_libc.h"
14a615b26e3e3c2da0b2f950f506f6c2c220430c19Sergey Matveev#include "sanitizer_common/sanitizer_platform.h"
15341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko#include "gtest/gtest.h"
16341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko
17a615b26e3e3c2da0b2f950f506f6c2c220430c19Sergey Matveev#if SANITIZER_LINUX || SANITIZER_MAC
184c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov# define SANITIZER_TEST_HAS_STAT_H 1
194c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov# include <sys/stat.h>
204c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#else
214c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov# define SANITIZER_TEST_HAS_STAT_H 0
224c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#endif
234c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
24341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// A regression test for internal_memmove() implementation.
25341588afadc46bf6f0dc7babd6d531209aba5202Alexander PotapenkoTEST(SanitizerCommon, InternalMemmoveRegression) {
26341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  char src[] = "Hello World";
27341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  char *dest = src + 6;
28341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  __sanitizer::internal_memmove(dest, src, 5);
29341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  EXPECT_EQ(dest[0], src[0]);
30341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  EXPECT_EQ(dest[4], src[4]);
31341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko}
32eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany
33eb2809311c94b73c269ccef8d68ae368642e5754Kostya SerebryanyTEST(SanitizerCommon, mem_is_zero) {
34eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  size_t size = 128;
35eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  char *x = new char[size];
36eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  memset(x, 0, size);
37eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  for (size_t pos = 0; pos < size; pos++) {
38eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    x[pos] = 1;
39eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    for (size_t beg = 0; beg < size; beg++) {
40eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany      for (size_t end = beg; end < size; end++) {
41eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany        // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
42eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany        if (beg <= pos && pos < end)
43eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany          EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
44eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany        else
45eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany          EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
46eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany      }
47eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    }
48eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    x[pos] = 0;
49eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  }
50eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  delete [] x;
51eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany}
524c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
532be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanovstruct stat_and_more {
542be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  struct stat st;
552be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  unsigned char z;
562be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov};
572be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: File manipulations are not yet supported on Windows
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32)
604c9317a7b61e136f832d2ede70f557963fd46bceAlexey SamsonovTEST(SanitizerCommon, FileOps) {
614c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  const char *str1 = "qwerty";
624c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  uptr len1 = internal_strlen(str1);
634c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  const char *str2 = "zxcv";
644c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  uptr len2 = internal_strlen(str2);
654c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
660fa691b7ec97d8c3948a637d6263822ed4e738f7Alexey Samsonov  u32 uid = GetUid();
670fa691b7ec97d8c3948a637d6263822ed4e738f7Alexey Samsonov  char temp_filename[128];
68a615b26e3e3c2da0b2f950f506f6c2c220430c19Sergey Matveev#if SANITIZER_ANDROID
69626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov  // I don't know a way to query temp directory location on Android without
70626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov  // going through Java interfaces. The code below is not ideal, but should
71626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov  // work. May require "adb root", but it is needed for almost any use of ASan
72626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov  // on Android already.
73626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov  internal_snprintf(temp_filename, sizeof(temp_filename),
74626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov                    "%s/sanitizer_common.tmp.%d",
75626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov                    GetEnv("EXTERNAL_STORAGE"), uid);
76626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov#else
77366984e3aa286f7b4fb45f5c9e703f2768c407edKostya Serebryany  internal_snprintf(temp_filename, sizeof(temp_filename),
78366984e3aa286f7b4fb45f5c9e703f2768c407edKostya Serebryany                    "/tmp/sanitizer_common.tmp.%d", uid);
79626e6fdd9c01c9b683c33656c2014ef9a2690e50Evgeniy Stepanov#endif
809578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  uptr openrv = OpenFile(temp_filename, true);
81411e828bf174dab9cfe7b64a5081cb870b71a73aKostya Serebryany  EXPECT_FALSE(internal_iserror(openrv));
829578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  fd_t fd = openrv;
834c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(len1, internal_write(fd, str1, len1));
844c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(len2, internal_write(fd, str2, len2));
854c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  internal_close(fd);
864c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
879578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  openrv = OpenFile(temp_filename, false);
88411e828bf174dab9cfe7b64a5081cb870b71a73aKostya Serebryany  EXPECT_FALSE(internal_iserror(openrv));
899578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  fd = openrv;
904c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  uptr fsize = internal_filesize(fd);
914c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(len1 + len2, fsize);
924c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
934c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#if SANITIZER_TEST_HAS_STAT_H
944c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  struct stat st1, st2, st3;
959578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  EXPECT_EQ(0u, internal_stat(temp_filename, &st1));
969578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  EXPECT_EQ(0u, internal_lstat(temp_filename, &st2));
979578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  EXPECT_EQ(0u, internal_fstat(fd, &st3));
984c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(fsize, (uptr)st3.st_size);
992be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov
1002be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  // Verify that internal_fstat does not write beyond the end of the supplied
1012be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  // buffer.
1022be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  struct stat_and_more sam;
1032be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  memset(&sam, 0xAB, sizeof(sam));
1049578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
1052be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  EXPECT_EQ(0xAB, sam.z);
1062be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  EXPECT_NE(0xAB, sam.st.st_size);
1072be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  EXPECT_NE(0, sam.st.st_size);
1084c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#endif
1094c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
1104c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  char buf[64] = {};
1114c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(len1, internal_read(fd, buf, len1));
1124c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
1134c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ((char)0, buf[len1 + 1]);
1144c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  internal_memset(buf, 0, len1);
1154c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(len2, internal_read(fd, buf, len2));
1164c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
1174c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  internal_close(fd);
1184c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov}
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1202be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov
12172870db5f2e0e83b2e925eef594dacfae275a8deAlexey SamsonovTEST(SanitizerCommon, InternalStrFunctions) {
12272870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  const char *haystack = "haystack";
12372870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
12472870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
12572870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(0, internal_strchr(haystack, 'z'));
12672870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));
12772870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov}
128