• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5355576307

23 Jun 2023 11:22AM UTC coverage: 91.735% (-0.001%) from 91.736%
5355576307

Pull #3595

github

web-flow
Merge 92dd5d647 into 92171c524
Pull Request #3595: Improve clang-tidy coverage

78150 of 85191 relevant lines covered (91.74%)

12467959.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.24
/src/fuzzer/mem_pool.cpp
1
/*
2
* (C) 2018 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "fuzzers.h"
8

9
#include <botan/internal/bit_ops.h>
10
#include <botan/internal/mem_pool.h>
11
#include <map>
12
#include <utility>
13
#include <vector>
14

15
#include <cstdlib>
16

17
namespace {
18

19
size_t compute_expected_alignment(size_t plen) {
195,282✔
20
   if(Botan::is_power_of_2(plen)) {
579,225✔
21
      return plen;
22
   } else {
23
      return 8;
188,661✔
24
   }
25
}
26

27
struct RawPage {
28
   public:
29
      RawPage(void* p) : m_p(p) {}
4✔
30

31
      ~RawPage() {
8✔
32
         // NOLINTNEXTLINE(*-no-malloc)
33
         std::free(m_p);
8✔
34
      }
4✔
35

36
      RawPage(const RawPage& other) = default;
37
      RawPage& operator=(const RawPage& other) = default;
38

39
      RawPage(RawPage&& other) noexcept : m_p(nullptr) { std::swap(m_p, other.m_p); }
4✔
40

41
      RawPage& operator=(RawPage&& other) noexcept {
42
         if(this != &other) {
43
            std::swap(m_p, other.m_p);
44
         }
45
         return (*this);
46
      }
47

48
      void* ptr() const { return m_p; }
4,000✔
49

50
   private:
51
      void* m_p;
52
};
53

54
std::vector<RawPage> allocate_raw_pages(size_t count, size_t page_size) {
1✔
55
   std::vector<RawPage> pages;
1✔
56
   pages.reserve(count);
1✔
57

58
   for(size_t i = 0; i != count; ++i) {
5✔
59
      void* ptr = nullptr;
4✔
60

61
      int rc = ::posix_memalign(&ptr, page_size, page_size);
4✔
62
      FUZZER_ASSERT_EQUAL(rc, 0);
4✔
63

64
      if(ptr) {
4✔
65
         pages.push_back(RawPage(ptr));
4✔
66
      }
67
   }
68

69
   return pages;
1✔
70
}
×
71

72
}  // namespace
73

74
void fuzz(const uint8_t in[], size_t in_len) {
1,000✔
75
   const size_t page_count = 4;
1,000✔
76
   const size_t page_size = 4096;
1,000✔
77

78
   // static to avoid repeated allocations
79
   static std::vector<RawPage> raw_mem = allocate_raw_pages(page_count, page_size);
1,000✔
80

81
   std::vector<void*> mem_pages;
1,000✔
82
   mem_pages.reserve(raw_mem.size());
1,000✔
83
   for(size_t i = 0; i != raw_mem.size(); ++i) {
5,000✔
84
      mem_pages.push_back(raw_mem[i].ptr());
4,000✔
85
   }
86

87
   Botan::Memory_Pool pool(mem_pages, page_size);
1,000✔
88
   std::map<uint8_t*, size_t> ptrs;
1,000✔
89

90
   while(in_len > 0) {
485,563✔
91
      const uint8_t op = in[0] % 2;
484,563✔
92
      size_t idx = (in[0] >> 1);
484,563✔
93
      in += 1;
484,563✔
94
      in_len -= 1;
484,563✔
95

96
      if(in_len > 0 && idx < 4) {
484,563✔
97
         idx = idx * 256 + in[0];
14,937✔
98
         in += 1;
14,937✔
99
         in_len -= 1;
14,937✔
100
      }
101

102
      if(op == 0) {
484,563✔
103
         const size_t plen = idx + 1;  // ensure non-zero
242,339✔
104
         uint8_t* p = static_cast<uint8_t*>(pool.allocate(plen));
242,339✔
105

106
         if(p) {
242,339✔
107
            const size_t expected_alignment = compute_expected_alignment(plen);
195,282✔
108
            const size_t alignment = reinterpret_cast<uintptr_t>(p) % expected_alignment;
195,282✔
109
            if(alignment != 0) {
195,282✔
110
               FUZZER_WRITE_AND_CRASH("Pointer allocated non-aligned pointer "
×
111
                                      << static_cast<void*>(p) << " for len " << plen << " expected "
112
                                      << expected_alignment << " got " << alignment);
113
            }
114

115
            //printf("alloc %d -> %p\n", plen, p);
116

117
            for(size_t i = 0; i != plen; ++i) {
14,432,800✔
118
               if(p[i] != 0) {
14,237,518✔
119
                  FUZZER_WRITE_AND_CRASH("Pool gave out non-zeroed memory");
14,237,518✔
120
               }
121
            }
122

123
            // verify it becomes zeroed later
124
            std::memset(p, static_cast<int>(idx), plen);
195,282✔
125

126
            auto insert = ptrs.insert(std::make_pair(p, plen));
195,282✔
127
            if(insert.second == false) {
195,282✔
128
               FUZZER_WRITE_AND_CRASH("Pointer " << static_cast<void*>(p) << " already existed\n");
×
129
            }
130

131
            auto itr = insert.first;
195,282✔
132

133
            // Verify this pointer doesn't overlap with the one before it
134
            if(itr != ptrs.begin()) {
195,282✔
135
               auto before = std::prev(itr);
113,290✔
136
               auto ptr_before = *before;
113,290✔
137

138
               if(ptr_before.first + ptr_before.second > p) {
113,290✔
139
                  FUZZER_WRITE_AND_CRASH("Previous " << static_cast<void*>(ptr_before.first) << "/" << ptr_before.second
×
140
                                                     << " overlaps with new " << static_cast<void*>(p));
141
               }
142
            }
143

144
            auto after = std::next(itr);
195,282✔
145

146
            if(after != ptrs.end()) {
195,282✔
147
               if(p + plen > after->first) {
94,970✔
148
                  FUZZER_WRITE_AND_CRASH("New " << static_cast<void*>(p) << "/" << plen << " overlaps following "
×
149
                                                << static_cast<void*>(after->first));
150
               }
151
            }
152
         }
153
      } else if(op == 1) {
242,224✔
154
         if(ptrs.empty()) {
242,224✔
155
            continue;
49,501✔
156
         }
157

158
         size_t which_ptr = idx % ptrs.size();
192,723✔
159

160
         auto itr = ptrs.begin();
192,723✔
161

162
         while(which_ptr-- > 0) {
192,723✔
163
            ++itr;
415,721✔
164
         }
165

166
         //printf("free %p %d\n", itr->first, itr->second);
167
         FUZZER_ASSERT_TRUE(pool.deallocate(itr->first, itr->second));
192,723✔
168
         ptrs.erase(itr);
192,723✔
169
      }
170
   }
171
}
2,000✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc