Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
smpi_memory: don't copy poisoned regions when AddressSanitizer is in use.
[simgrid.git] / src / smpi / internals / smpi_memory.cpp
index 719b28b..f96a486 100644 (file)
@@ -9,13 +9,13 @@
 
 #include <vector>
 
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdio.h>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <errno.h>
+#include <sys/types.h>
 
 #ifndef WIN32
 #include <sys/mman.h>
@@ -68,6 +68,30 @@ void smpi_get_executable_global_size()
 }
 #endif
 
+#if !defined(__has_feature)
+#define __has_feature(x) 0
+#endif
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+#include <sanitizer/asan_interface.h>
+void* safe_memcpy(void* dest, void* src, size_t n)
+{
+  char* psrc  = static_cast<char*>(src);
+  char* pdest = static_cast<char*>(dest);
+  for (size_t i = 0; i < n;) {
+    while (i < n && __asan_address_is_poisoned(psrc + i))
+      ++i;
+    if (i < n) {
+      char* p  = static_cast<char*>(__asan_region_is_poisoned(psrc + i, n - i));
+      size_t j = p ? (p - psrc) : n;
+      memcpy(pdest + i, psrc + i, j - i);
+      i = j;
+    }
+  }
+  return dest;
+}
+#else
+#define safe_memcpy(dest, src, n) memcpy(dest, src, n)
+#endif
 
 /** Map a given SMPI privatization segment (make a SMPI process active) */
 void smpi_switch_data_segment(int dest) {
@@ -91,7 +115,7 @@ void smpi_really_switch_data_segment(int dest)
 #if HAVE_PRIVATIZATION
   if(smpi_loaded_page==-1){//initial switch, do the copy from the real page here
     for (int i=0; i< smpi_process_count(); i++){
-      memcpy(smpi_privatization_regions[i].address, TOPAGE(smpi_start_data_exe), smpi_size_data_exe);
+      safe_memcpy(smpi_privatization_regions[i].address, TOPAGE(smpi_start_data_exe), smpi_size_data_exe);
     }
   }
 
@@ -108,7 +132,8 @@ void smpi_really_switch_data_segment(int dest)
 
 int smpi_is_privatization_file(char* file)
 {
-  return strncmp("/dev/shm/my-buffer-", file, std::strlen("/dev/shm/my-buffer-")) == 0;
+  const std::string buffer_path("/dev/shm/my-buffer-");
+  return buffer_path.compare(0, std::string::npos, file, buffer_path.length()) == 0;
 }
 
 void smpi_initialize_global_memory_segments()
@@ -135,7 +160,7 @@ void smpi_initialize_global_memory_segments()
     int status;
 
     do {
-      snprintf(path, sizeof(path), "/smpi-buffer-%06x", rand() % 0xffffff);
+      snprintf(path, sizeof(path), "/smpi-buffer-%06x", rand() % 0xffffffU);
       file_descriptor = shm_open(path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
     } while (file_descriptor == -1 && errno == EEXIST);
     if (file_descriptor < 0) {
@@ -171,7 +196,7 @@ Ask the Internet about tutorials on how to increase the files limit such as: htt
       xbt_die("Impossible to unlink temporary file for memory mapping");
 
     // initialize the values
-    memcpy(address, TOPAGE(smpi_start_data_exe), smpi_size_data_exe);
+    safe_memcpy(address, TOPAGE(smpi_start_data_exe), smpi_size_data_exe);
 
     // store the address of the mapping for further switches
     smpi_privatization_regions[i].file_descriptor = file_descriptor;