[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