Home | History | Annotate | Line # | Download | only in fuzzer
      1  1.1  kamil //===- FuzzerShmemPosix.cpp - Posix shared memory ---------------*- C++ -* ===//
      2  1.1  kamil //
      3  1.1  kamil //                     The LLVM Compiler Infrastructure
      4  1.1  kamil //
      5  1.1  kamil // This file is distributed under the University of Illinois Open Source
      6  1.1  kamil // License. See LICENSE.TXT for details.
      7  1.1  kamil //
      8  1.1  kamil //===----------------------------------------------------------------------===//
      9  1.1  kamil // SharedMemoryRegion
     10  1.1  kamil //===----------------------------------------------------------------------===//
     11  1.1  kamil #include "FuzzerDefs.h"
     12  1.1  kamil #if LIBFUZZER_POSIX
     13  1.1  kamil 
     14  1.1  kamil #include "FuzzerIO.h"
     15  1.1  kamil #include "FuzzerShmem.h"
     16  1.1  kamil 
     17  1.1  kamil #include <errno.h>
     18  1.1  kamil #include <fcntl.h>
     19  1.1  kamil #include <semaphore.h>
     20  1.1  kamil #include <stdio.h>
     21  1.1  kamil #include <stdlib.h>
     22  1.1  kamil #include <sys/mman.h>
     23  1.1  kamil #include <sys/stat.h>
     24  1.1  kamil #include <sys/types.h>
     25  1.1  kamil #include <unistd.h>
     26  1.1  kamil 
     27  1.1  kamil namespace fuzzer {
     28  1.1  kamil 
     29  1.1  kamil std::string SharedMemoryRegion::Path(const char *Name) {
     30  1.1  kamil   return DirPlusFile(TmpDir(), Name);
     31  1.1  kamil }
     32  1.1  kamil 
     33  1.1  kamil std::string SharedMemoryRegion::SemName(const char *Name, int Idx) {
     34  1.1  kamil   std::string Res(Name);
     35  1.1  kamil   // When passing a name without a leading <slash> character to
     36  1.1  kamil   // sem_open, the behaviour is unspecified in POSIX. Add a leading
     37  1.1  kamil   // <slash> character for the name if there is no such one.
     38  1.1  kamil   if (!Res.empty() && Res[0] != '/')
     39  1.1  kamil     Res.insert(Res.begin(), '/');
     40  1.1  kamil   return Res + (char)('0' + Idx);
     41  1.1  kamil }
     42  1.1  kamil 
     43  1.1  kamil bool SharedMemoryRegion::Map(int fd) {
     44  1.1  kamil   Data =
     45  1.1  kamil       (uint8_t *)mmap(0, kShmemSize, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
     46  1.1  kamil   if (Data == (uint8_t*)-1)
     47  1.1  kamil     return false;
     48  1.1  kamil   return true;
     49  1.1  kamil }
     50  1.1  kamil 
     51  1.1  kamil bool SharedMemoryRegion::Create(const char *Name) {
     52  1.1  kamil   int fd = open(Path(Name).c_str(), O_CREAT | O_RDWR, 0777);
     53  1.1  kamil   if (fd < 0) return false;
     54  1.1  kamil   if (ftruncate(fd, kShmemSize) < 0) return false;
     55  1.1  kamil   if (!Map(fd))
     56  1.1  kamil     return false;
     57  1.1  kamil   for (int i = 0; i < 2; i++) {
     58  1.1  kamil     sem_unlink(SemName(Name, i).c_str());
     59  1.1  kamil     Semaphore[i] = sem_open(SemName(Name, i).c_str(), O_CREAT, 0644, 0);
     60  1.1  kamil     if (Semaphore[i] == SEM_FAILED)
     61  1.1  kamil       return false;
     62  1.1  kamil   }
     63  1.1  kamil   IAmServer = true;
     64  1.1  kamil   return true;
     65  1.1  kamil }
     66  1.1  kamil 
     67  1.1  kamil bool SharedMemoryRegion::Open(const char *Name) {
     68  1.1  kamil   int fd = open(Path(Name).c_str(), O_RDWR);
     69  1.1  kamil   if (fd < 0) return false;
     70  1.1  kamil   struct stat stat_res;
     71  1.1  kamil   if (0 != fstat(fd, &stat_res))
     72  1.1  kamil     return false;
     73  1.1  kamil   assert(stat_res.st_size == kShmemSize);
     74  1.1  kamil   if (!Map(fd))
     75  1.1  kamil     return false;
     76  1.1  kamil   for (int i = 0; i < 2; i++) {
     77  1.1  kamil     Semaphore[i] = sem_open(SemName(Name, i).c_str(), 0);
     78  1.1  kamil     if (Semaphore[i] == SEM_FAILED)
     79  1.1  kamil       return false;
     80  1.1  kamil   }
     81  1.1  kamil   IAmServer = false;
     82  1.1  kamil   return true;
     83  1.1  kamil }
     84  1.1  kamil 
     85  1.1  kamil bool SharedMemoryRegion::Destroy(const char *Name) {
     86  1.1  kamil   return 0 == unlink(Path(Name).c_str());
     87  1.1  kamil }
     88  1.1  kamil 
     89  1.1  kamil void SharedMemoryRegion::Post(int Idx) {
     90  1.1  kamil   assert(Idx == 0 || Idx == 1);
     91  1.1  kamil   sem_post((sem_t*)Semaphore[Idx]);
     92  1.1  kamil }
     93  1.1  kamil 
     94  1.1  kamil void SharedMemoryRegion::Wait(int Idx) {
     95  1.1  kamil   assert(Idx == 0 || Idx == 1);
     96  1.1  kamil   for (int i = 0; i < 10 && sem_wait((sem_t*)Semaphore[Idx]); i++) {
     97  1.1  kamil     // sem_wait may fail if interrupted by a signal.
     98  1.1  kamil     sleep(i);
     99  1.1  kamil     if (i)
    100  1.1  kamil       Printf("%s: sem_wait[%d] failed %s\n", i < 9 ? "WARNING" : "ERROR", i,
    101  1.1  kamil              strerror(errno));
    102  1.1  kamil     if (i == 9) abort();
    103  1.1  kamil   }
    104  1.1  kamil }
    105  1.1  kamil 
    106  1.1  kamil }  // namespace fuzzer
    107  1.1  kamil 
    108  1.1  kamil #endif  // LIBFUZZER_POSIX
    109