Home | History | Annotate | Download | only in Linux
      1 // Test fopencookie interceptor.
      2 // RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t
      3 // RUN: %clangxx_msan -std=c++11 -fsanitize-memory-track-origins -O0 %s -o %t && %run %t
      4 
      5 #include <assert.h>
      6 #include <pthread.h>
      7 #include <stdint.h>
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 #include <string.h>
     11 
     12 #include <sanitizer/msan_interface.h>
     13 
     14 constexpr uintptr_t kMagicCookie = 0x12345678;
     15 
     16 static ssize_t cookie_read(void *cookie, char *buf, size_t size) {
     17   assert((uintptr_t)cookie == kMagicCookie);
     18   memset(buf, 0, size);
     19   return 0;
     20 }
     21 
     22 static ssize_t cookie_write(void *cookie, const char *buf, size_t size) {
     23   assert((uintptr_t)cookie == kMagicCookie);
     24   __msan_check_mem_is_initialized(buf, size);
     25   return 0;
     26 }
     27 
     28 static int cookie_seek(void *cookie, off64_t *offset, int whence) {
     29   assert((uintptr_t)cookie == kMagicCookie);
     30   __msan_check_mem_is_initialized(offset, sizeof(*offset));
     31   return 0;
     32 }
     33 
     34 static int cookie_close(void *cookie) {
     35   assert((uintptr_t)cookie == kMagicCookie);
     36   return 0;
     37 }
     38 
     39 void PoisonStack() { char a[8192]; }
     40 
     41 void TestPoisonStack() {
     42   // Verify that PoisonStack has poisoned the stack - otherwise this test is not
     43   // testing anything.
     44   char a;
     45   assert(__msan_test_shadow(&a - 1000, 1) == 0);
     46 }
     47 
     48 int main() {
     49   void *cookie = (void *)kMagicCookie;
     50   FILE *f = fopencookie(cookie, "rw",
     51                         {cookie_read, cookie_write, cookie_seek, cookie_close});
     52   PoisonStack();
     53   TestPoisonStack();
     54   fseek(f, 100, SEEK_SET);
     55   char buf[50];
     56   fread(buf, 50, 1, f);
     57   fwrite(buf, 50, 1, f);
     58   fclose(f);
     59 
     60   f = fopencookie(cookie, "rw", {nullptr, nullptr, nullptr, nullptr});
     61   fseek(f, 100, SEEK_SET);
     62   fread(buf, 50, 1, f);
     63   fwrite(buf, 50, 1, f);
     64   fclose(f);
     65 }
     66