[compiler-rt] r224819 - [sanitizer] mmap2 syscall works with 4096-byte units instead of bytes.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Wed Dec 24 04:58:09 PST 2014


Author: eugenis
Date: Wed Dec 24 06:58:09 2014
New Revision: 224819

URL: http://llvm.org/viewvc/llvm-project?rev=224819&view=rev
Log:
[sanitizer] mmap2 syscall works with 4096-byte units instead of bytes.

Ouch.

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=224819&r1=224818&r2=224819&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Wed Dec 24 06:58:09 2014
@@ -109,14 +109,16 @@ namespace __sanitizer {
 #endif
 
 // --------------- sanitizer_libc.h
-uptr internal_mmap(void *addr, uptr length, int prot, int flags,
-                    int fd, u64 offset) {
+uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
+                   u64 offset) {
 #if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
   return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd,
                           offset);
 #else
+  // mmap2 specifies file offset in 4096-byte units.
+  CHECK(IsAligned(offset, 4096));
   return internal_syscall(SYSCALL(mmap2), addr, length, prot, flags, fd,
-                          offset);
+                          offset / 4096);
 #endif
 }
 

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc?rev=224819&r1=224818&r2=224819&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_libc_test.cc Wed Dec 24 06:58:09 2014
@@ -55,6 +55,19 @@ struct stat_and_more {
   unsigned char z;
 };
 
+static void temp_file_name(char *buf, size_t bufsize, const char *prefix) {
+  const char *tmpdir = "/tmp";
+#if SANITIZER_ANDROID
+  // I don't know a way to query temp directory location on Android without
+  // going through Java interfaces. The code below is not ideal, but should
+  // work. May require "adb root", but it is needed for almost any use of ASan
+  // on Android already.
+  tmpdir = GetEnv("EXTERNAL_STORAGE");
+#endif
+  u32 uid = GetUid();
+  internal_snprintf(buf, bufsize, "%s/%s%d", tmpdir, prefix, uid);
+}
+
 // FIXME: File manipulations are not yet supported on Windows
 #if !defined(_WIN32)
 TEST(SanitizerCommon, FileOps) {
@@ -63,28 +76,16 @@ TEST(SanitizerCommon, FileOps) {
   const char *str2 = "zxcv";
   uptr len2 = internal_strlen(str2);
 
-  u32 uid = GetUid();
-  char temp_filename[128];
-#if SANITIZER_ANDROID
-  // I don't know a way to query temp directory location on Android without
-  // going through Java interfaces. The code below is not ideal, but should
-  // work. May require "adb root", but it is needed for almost any use of ASan
-  // on Android already.
-  internal_snprintf(temp_filename, sizeof(temp_filename),
-                    "%s/sanitizer_common.tmp.%d",
-                    GetEnv("EXTERNAL_STORAGE"), uid);
-#else
-  internal_snprintf(temp_filename, sizeof(temp_filename),
-                    "/tmp/sanitizer_common.tmp.%d", uid);
-#endif
-  uptr openrv = OpenFile(temp_filename, true);
+  char tmpfile[128];
+  temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp.");
+  uptr openrv = OpenFile(tmpfile, true);
   EXPECT_FALSE(internal_iserror(openrv));
   fd_t fd = openrv;
   EXPECT_EQ(len1, internal_write(fd, str1, len1));
   EXPECT_EQ(len2, internal_write(fd, str2, len2));
   internal_close(fd);
 
-  openrv = OpenFile(temp_filename, false);
+  openrv = OpenFile(tmpfile, false);
   EXPECT_FALSE(internal_iserror(openrv));
   fd = openrv;
   uptr fsize = internal_filesize(fd);
@@ -92,8 +93,8 @@ TEST(SanitizerCommon, FileOps) {
 
 #if SANITIZER_TEST_HAS_STAT_H
   struct stat st1, st2, st3;
-  EXPECT_EQ(0u, internal_stat(temp_filename, &st1));
-  EXPECT_EQ(0u, internal_lstat(temp_filename, &st2));
+  EXPECT_EQ(0u, internal_stat(tmpfile, &st1));
+  EXPECT_EQ(0u, internal_lstat(tmpfile, &st2));
   EXPECT_EQ(0u, internal_fstat(fd, &st3));
   EXPECT_EQ(fsize, (uptr)st3.st_size);
 
@@ -115,6 +116,7 @@ TEST(SanitizerCommon, FileOps) {
   EXPECT_EQ(len2, internal_read(fd, buf, len2));
   EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
   internal_close(fd);
+  internal_unlink(tmpfile);
 }
 #endif
 
@@ -125,3 +127,29 @@ TEST(SanitizerCommon, InternalStrFunctio
   EXPECT_EQ(0, internal_strchr(haystack, 'z'));
   EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));
 }
+
+TEST(SanitizerCommon, InternalMmapWithOffset) {
+  char tmpfile[128];
+  temp_file_name(tmpfile, sizeof(tmpfile),
+                 "sanitizer_common.internalmmapwithoffset.tmp.");
+  uptr res = OpenFile(tmpfile, true);
+  ASSERT_FALSE(internal_iserror(res));
+  fd_t fd = res;
+
+  uptr page_size = GetPageSizeCached();
+  res = internal_ftruncate(fd, page_size * 2);
+  ASSERT_FALSE(internal_iserror(res));
+
+  internal_lseek(fd, page_size, SEEK_SET);
+  internal_write(fd, "AB", 2);
+
+  char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size);
+  ASSERT_NE(nullptr, p);
+
+  ASSERT_EQ('A', p[0]);
+  ASSERT_EQ('B', p[1]);
+
+  internal_close(fd);
+  internal_munmap(p, page_size);
+  internal_unlink(tmpfile);
+}





More information about the llvm-commits mailing list