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> 20909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar# include "sanitizer_common/sanitizer_posix.h" 214c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#else 224c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov# define SANITIZER_TEST_HAS_STAT_H 0 234c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#endif 244c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov 25341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// A regression test for internal_memmove() implementation. 26341588afadc46bf6f0dc7babd6d531209aba5202Alexander PotapenkoTEST(SanitizerCommon, InternalMemmoveRegression) { 27341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko char src[] = "Hello World"; 28341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko char *dest = src + 6; 29341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko __sanitizer::internal_memmove(dest, src, 5); 30341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko EXPECT_EQ(dest[0], src[0]); 31341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko EXPECT_EQ(dest[4], src[4]); 32341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko} 33eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany 34eb2809311c94b73c269ccef8d68ae368642e5754Kostya SerebryanyTEST(SanitizerCommon, mem_is_zero) { 35eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany size_t size = 128; 36eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany char *x = new char[size]; 37eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany memset(x, 0, size); 38eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany for (size_t pos = 0; pos < size; pos++) { 39eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany x[pos] = 1; 40eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany for (size_t beg = 0; beg < size; beg++) { 41eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany for (size_t end = beg; end < size; end++) { 42eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end); 43eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany if (beg <= pos && pos < end) 44eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg)); 45eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany else 46eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg)); 47eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany } 48eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany } 49eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany x[pos] = 0; 50eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany } 51eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany delete [] x; 52eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany} 534c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov 542be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanovstruct stat_and_more { 552be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov struct stat st; 562be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov unsigned char z; 572be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov}; 582be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov 5986277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic void temp_file_name(char *buf, size_t bufsize, const char *prefix) { 6086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *tmpdir = "/tmp"; 6186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_ANDROID 6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // I don't know a way to query temp directory location on Android without 6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // going through Java interfaces. The code below is not ideal, but should 6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // work. May require "adb root", but it is needed for almost any use of ASan 6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // on Android already. 6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines tmpdir = GetEnv("EXTERNAL_STORAGE"); 6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif 6886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines u32 uid = GetUid(); 6986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_snprintf(buf, bufsize, "%s/%s%d", tmpdir, prefix, uid); 7086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 7186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: File manipulations are not yet supported on Windows 732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) 744c9317a7b61e136f832d2ede70f557963fd46bceAlexey SamsonovTEST(SanitizerCommon, FileOps) { 754c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov const char *str1 = "qwerty"; 764c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov uptr len1 = internal_strlen(str1); 774c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov const char *str2 = "zxcv"; 784c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov uptr len2 = internal_strlen(str2); 794c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov 8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char tmpfile[128]; 8186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp."); 82909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar fd_t fd = OpenFile(tmpfile, WrOnly); 83909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASSERT_NE(fd, kInvalidFd); 844c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov EXPECT_EQ(len1, internal_write(fd, str1, len1)); 854c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov EXPECT_EQ(len2, internal_write(fd, str2, len2)); 86909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar CloseFile(fd); 874c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov 88909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar fd = OpenFile(tmpfile, RdOnly); 89909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASSERT_NE(fd, kInvalidFd); 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; 9586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines EXPECT_EQ(0u, internal_stat(tmpfile, &st1)); 9686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines EXPECT_EQ(0u, internal_lstat(tmpfile, &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)); 117909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar CloseFile(fd); 11886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_unlink(tmpfile); 1194c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov} 1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 1212be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov 12272870db5f2e0e83b2e925eef594dacfae275a8deAlexey SamsonovTEST(SanitizerCommon, InternalStrFunctions) { 12372870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov const char *haystack = "haystack"; 12472870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y')); 12572870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y')); 12672870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov EXPECT_EQ(0, internal_strchr(haystack, 'z')); 12772870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z')); 12872870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov} 12986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 13086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// FIXME: File manipulations are not yet supported on Windows 13186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !defined(_WIN32) && !SANITIZER_MAC 13286277eb844c4983c81de62d7c050e92fe7155788Stephen HinesTEST(SanitizerCommon, InternalMmapWithOffset) { 13386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char tmpfile[128]; 13486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines temp_file_name(tmpfile, sizeof(tmpfile), 13586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "sanitizer_common.internalmmapwithoffset.tmp."); 136909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar fd_t fd = OpenFile(tmpfile, RdWr); 137909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASSERT_NE(fd, kInvalidFd); 13886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 13986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr page_size = GetPageSizeCached(); 140909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar uptr res = internal_ftruncate(fd, page_size * 2); 14186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASSERT_FALSE(internal_iserror(res)); 14286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 14386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines res = internal_lseek(fd, page_size, SEEK_SET); 14486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASSERT_FALSE(internal_iserror(res)); 14586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 14686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines res = internal_write(fd, "AB", 2); 14786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASSERT_FALSE(internal_iserror(res)); 14886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 14986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size); 15086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASSERT_NE(nullptr, p); 15186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 15286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASSERT_EQ('A', p[0]); 15386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASSERT_EQ('B', p[1]); 15486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 155909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar CloseFile(fd); 156909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar UnmapOrDie(p, page_size); 15786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_unlink(tmpfile); 15886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 15986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif 160