[compiler-rt] r181311 - [sanitizer] Sanitizer __internal_*stat interface.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue May 7 05:47:05 PDT 2013


Author: eugenis
Date: Tue May  7 07:47:04 2013
New Revision: 181311

URL: http://llvm.org/viewvc/llvm-project?rev=181311&view=rev
Log:
[sanitizer] Sanitizer __internal_*stat interface.

With this change, __internal_*stat always expect a "struct stat *" argument.
This avoids stat/stat64 caller-side confusion (sanitizer_common tests already
made this mistake), and allows the use of __internal_fstat() as a drop-in
replacement for libc's fstat().

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=181311&r1=181310&r2=181311&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Tue May  7 07:47:04 2013
@@ -108,11 +108,34 @@ uptr internal_write(fd_t fd, const void
   return res;
 }
 
+#if !SANITIZER_LINUX_USES_64BIT_SYSCALLS
+static void stat64_to_stat(struct stat64 *in, struct stat *out) {
+  internal_memset(out, 0, sizeof(*out));
+  out->st_dev = in->st_dev;
+  out->st_ino = in->st_ino;
+  out->st_mode = in->st_mode;
+  out->st_nlink = in->st_nlink;
+  out->st_uid = in->st_uid;
+  out->st_gid = in->st_gid;
+  out->st_rdev = in->st_rdev;
+  out->st_size = in->st_size;
+  out->st_blksize = in->st_blksize;
+  out->st_blocks = in->st_blocks;
+  out->st_atime = in->st_atime;
+  out->st_mtime = in->st_mtime;
+  out->st_ctime = in->st_ctime;
+  out->st_ino = in->st_ino;
+}
+#endif
+
 int internal_stat(const char *path, void *buf) {
 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
   return syscall(__NR_stat, path, buf);
 #else
-  return syscall(__NR_stat64, path, buf);
+  struct stat64 buf64;
+  int res = syscall(__NR_stat64, path, &buf64);
+  stat64_to_stat(&buf64, (struct stat *)buf);
+  return res;
 #endif
 }
 
@@ -120,7 +143,10 @@ int internal_lstat(const char *path, voi
 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
   return syscall(__NR_lstat, path, buf);
 #else
-  return syscall(__NR_lstat64, path, buf);
+  struct stat64 buf64;
+  int res = syscall(__NR_lstat64, path, &buf64);
+  stat64_to_stat(&buf64, (struct stat *)buf);
+  return res;
 #endif
 }
 
@@ -128,16 +154,15 @@ int internal_fstat(fd_t fd, void *buf) {
 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
   return syscall(__NR_fstat, fd, buf);
 #else
-  return syscall(__NR_fstat64, fd, buf);
+  struct stat64 buf64;
+  int res = syscall(__NR_fstat64, fd, &buf64);
+  stat64_to_stat(&buf64, (struct stat *)buf);
+  return res;
 #endif
 }
 
 uptr internal_filesize(fd_t fd) {
-#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
   struct stat st;
-#else
-  struct stat64 st;
-#endif
   if (internal_fstat(fd, &st))
     return -1;
   return (uptr)st.st_size;
@@ -166,15 +191,9 @@ void internal__exit(int exitcode) {
 
 // ----------------- sanitizer_common.h
 bool FileExists(const char *filename) {
-#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
   struct stat st;
-  if (syscall(__NR_stat, filename, &st))
+  if (internal_stat(filename, &st))
     return false;
-#else
-  struct stat64 st;
-  if (syscall(__NR_stat64, filename, &st))
-    return false;
-#endif
   // Sanity check: filename is a regular file.
   return S_ISREG(st.st_mode);
 }

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=181311&r1=181310&r2=181311&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 Tue May  7 07:47:04 2013
@@ -49,6 +49,11 @@ TEST(SanitizerCommon, mem_is_zero) {
   delete [] x;
 }
 
+struct stat_and_more {
+  struct stat st;
+  unsigned char z;
+};
+
 TEST(SanitizerCommon, FileOps) {
   const char *str1 = "qwerty";
   uptr len1 = internal_strlen(str1);
@@ -86,6 +91,15 @@ TEST(SanitizerCommon, FileOps) {
   EXPECT_EQ(0, internal_lstat(temp_filename, &st2));
   EXPECT_EQ(0, internal_fstat(fd, &st3));
   EXPECT_EQ(fsize, (uptr)st3.st_size);
+
+  // Verify that internal_fstat does not write beyond the end of the supplied
+  // buffer.
+  struct stat_and_more sam;
+  memset(&sam, 0xAB, sizeof(sam));
+  EXPECT_EQ(0, internal_fstat(fd, &sam.st));
+  EXPECT_EQ(0xAB, sam.z);
+  EXPECT_NE(0xAB, sam.st.st_size);
+  EXPECT_NE(0, sam.st.st_size);
 #endif
 
   char buf[64] = {};
@@ -97,3 +111,4 @@ TEST(SanitizerCommon, FileOps) {
   EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
   internal_close(fd);
 }
+





More information about the llvm-commits mailing list