Coverage Report

Created: 2018-09-25 14:53

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