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

randombit / botan / 5111374265

29 May 2023 11:19AM UTC coverage: 92.227% (+0.5%) from 91.723%
5111374265

push

github

randombit
Next release will be 3.1.0. Update release notes

75588 of 81959 relevant lines covered (92.23%)

11886470.91 hits per line

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

93.06
/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,238✔
20
   if(Botan::is_power_of_2(plen)) {
579,115✔
21
      return plen;
22
   } else {
23
      return 8;
188,639✔
24
   }
25
}
26

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

31
      ~RawPage() { std::free(m_p); }
4✔
32

33
      RawPage(const RawPage& other) = default;
34
      RawPage& operator=(const RawPage& other) = default;
35

36
      RawPage(RawPage&& other) : m_p(nullptr) { std::swap(m_p, other.m_p); }
4✔
37

38
      RawPage& operator=(RawPage&& other) {
39
         if(this != &other) {
40
            std::swap(m_p, other.m_p);
41
         }
42
         return (*this);
43
      }
44

45
      void* ptr() const { return m_p; }
4,000✔
46

47
   private:
48
      void* m_p;
49
};
50

51
std::vector<RawPage> allocate_raw_pages(size_t count, size_t page_size) {
1✔
52
   std::vector<RawPage> pages;
1✔
53
   pages.reserve(count);
1✔
54

55
   for(size_t i = 0; i != count; ++i) {
5✔
56
      void* ptr = nullptr;
4✔
57

58
      int rc = ::posix_memalign(&ptr, page_size, page_size);
4✔
59
      FUZZER_ASSERT_EQUAL(rc, 0);
4✔
60

61
      if(ptr) {
4✔
62
         pages.push_back(RawPage(ptr));
4✔
63
      }
64
   }
65

66
   return pages;
1✔
67
}
×
68

69
}  // namespace
70

71
void fuzz(const uint8_t in[], size_t in_len) {
1,000✔
72
   const size_t page_count = 4;
1,000✔
73
   const size_t page_size = 4096;
1,000✔
74

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

78
   std::vector<void*> mem_pages;
1,000✔
79
   mem_pages.reserve(raw_mem.size());
1,000✔
80
   for(size_t i = 0; i != raw_mem.size(); ++i)
5,000✔
81
      mem_pages.push_back(raw_mem[i].ptr());
4,000✔
82

83
   Botan::Memory_Pool pool(mem_pages, page_size);
1,000✔
84
   std::map<uint8_t*, size_t> ptrs;
1,000✔
85

86
   while(in_len > 0) {
485,148✔
87
      const uint8_t op = in[0] % 2;
484,148✔
88
      size_t idx = (in[0] >> 1);
484,148✔
89
      in += 1;
484,148✔
90
      in_len -= 1;
484,148✔
91

92
      if(in_len > 0 && idx < 4) {
484,148✔
93
         idx = idx * 256 + in[0];
15,352✔
94
         in += 1;
15,352✔
95
         in_len -= 1;
15,352✔
96
      }
97

98
      if(op == 0) {
484,148✔
99
         const size_t plen = idx + 1;  // ensure non-zero
241,557✔
100
         uint8_t* p = static_cast<uint8_t*>(pool.allocate(plen));
241,557✔
101

102
         if(p) {
241,557✔
103
            const size_t expected_alignment = compute_expected_alignment(plen);
195,238✔
104
            const size_t alignment = reinterpret_cast<uintptr_t>(p) % expected_alignment;
195,238✔
105
            if(alignment != 0) {
195,238✔
106
               FUZZER_WRITE_AND_CRASH("Pointer allocated non-aligned pointer "
×
107
                                      << static_cast<void*>(p) << " for len " << plen << " expected "
108
                                      << expected_alignment << " got " << alignment);
109
            }
110

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

113
            for(size_t i = 0; i != plen; ++i) {
14,424,628✔
114
               if(p[i] != 0) {
14,229,390✔
115
                  FUZZER_WRITE_AND_CRASH("Pool gave out non-zeroed memory");
14,229,390✔
116
               }
117
            }
118

119
            // verify it becomes zeroed later
120
            std::memset(p, static_cast<int>(idx), plen);
195,238✔
121

122
            auto insert = ptrs.insert(std::make_pair(p, plen));
195,238✔
123
            if(insert.second == false) {
195,238✔
124
               FUZZER_WRITE_AND_CRASH("Pointer " << static_cast<void*>(p) << " already existed\n");
×
125
            }
126

127
            auto itr = insert.first;
195,238✔
128

129
            // Verify this pointer doesn't overlap with the one before it
130
            if(itr != ptrs.begin()) {
195,238✔
131
               auto before = std::prev(itr);
112,679✔
132
               auto ptr_before = *before;
112,679✔
133

134
               if(ptr_before.first + ptr_before.second > p) {
112,679✔
135
                  FUZZER_WRITE_AND_CRASH("Previous " << static_cast<void*>(ptr_before.first) << "/" << ptr_before.second
×
136
                                                     << " overlaps with new " << static_cast<void*>(p));
137
               }
138
            }
139

140
            auto after = std::next(itr);
195,238✔
141

142
            if(after != ptrs.end()) {
195,238✔
143
               if(p + plen > after->first) {
94,426✔
144
                  FUZZER_WRITE_AND_CRASH("New " << static_cast<void*>(p) << "/" << plen << " overlaps following "
×
145
                                                << static_cast<void*>(after->first));
146
               }
147
            }
148
         }
149
      } else if(op == 1) {
242,591✔
150
         if(ptrs.empty())
242,591✔
151
            continue;
49,950✔
152

153
         size_t which_ptr = idx % ptrs.size();
192,641✔
154

155
         auto itr = ptrs.begin();
192,641✔
156

157
         while(which_ptr-- > 0) {
192,641✔
158
            ++itr;
412,352✔
159
         }
160

161
         //printf("free %p %d\n", itr->first, itr->second);
162
         FUZZER_ASSERT_TRUE(pool.deallocate(itr->first, itr->second));
192,641✔
163
         ptrs.erase(itr);
192,641✔
164
      }
165
   }
166
}
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