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

randombit / botan / 11428340676

20 Oct 2024 05:39PM UTC coverage: 91.134%. Remained the same
11428340676

Pull #4397

github

web-flow
Merge d008c3e10 into 6babd8226
Pull Request #4397: Reduce risk of compiler value range propogation in FrodoKEM sampling

91050 of 99908 relevant lines covered (91.13%)

9314704.14 hits per line

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

84.21
/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) {
96,740✔
20
   if(Botan::is_power_of_2(plen)) {
286,558✔
21
      return plen;
22
   } else {
23
      return 8;
93,078✔
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(std::span<const uint8_t> in) {
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
   size_t in_len = in.size();
1,000✔
91
   auto x = in.data();
1,000✔
92
   while(in_len > 0) {
494,394✔
93
      const uint8_t op = in[0] % 2;
493,394✔
94
      size_t idx = (in[0] >> 1);
493,394✔
95
      x += 1;
493,394✔
96
      in_len -= 1;
493,394✔
97

98
      if(in_len > 0 && idx < 4) {
493,394✔
99
         idx = idx * 256 + x[0];
6,106✔
100
         x += 1;
6,106✔
101
         in_len -= 1;
6,106✔
102
      }
103

104
      if(op == 0) {
493,394✔
105
         const size_t plen = idx + 1;  // ensure non-zero
245,275✔
106
         uint8_t* p = static_cast<uint8_t*>(pool.allocate(plen));
245,275✔
107

108
         if(p) {
245,275✔
109
            const size_t expected_alignment = compute_expected_alignment(plen);
96,740✔
110
            const size_t alignment = reinterpret_cast<uintptr_t>(p) % expected_alignment;
96,740✔
111
            if(alignment != 0) {
96,740✔
112
               FUZZER_WRITE_AND_CRASH("Pointer allocated non-aligned pointer "
×
113
                                      << static_cast<void*>(p) << " for len " << plen << " expected "
114
                                      << expected_alignment << " got " << alignment);
115
            }
116

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

119
            for(size_t i = 0; i != plen; ++i) {
5,891,600✔
120
               if(p[i] != 0) {
5,794,860✔
121
                  FUZZER_WRITE_AND_CRASH("Pool gave out non-zeroed memory");
5,794,860✔
122
               }
123
            }
124

125
            // verify it becomes zeroed later
126
            std::memset(p, static_cast<int>(idx), plen);
96,740✔
127

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

133
            auto itr = insert.first;
96,740✔
134

135
            // Verify this pointer doesn't overlap with the one before it
136
            if(itr != ptrs.begin()) {
96,740✔
137
               auto before = std::prev(itr);
96,280✔
138
               auto ptr_before = *before;
96,280✔
139

140
               if(ptr_before.first + ptr_before.second > p) {
96,280✔
141
                  FUZZER_WRITE_AND_CRASH("Previous " << static_cast<void*>(ptr_before.first) << "/" << ptr_before.second
×
142
                                                     << " overlaps with new " << static_cast<void*>(p));
143
               }
144
            }
145

146
            auto after = std::next(itr);
96,740✔
147

148
            if(after != ptrs.end()) {
96,740✔
149
               if(p + plen > after->first) {
×
150
                  FUZZER_WRITE_AND_CRASH("New " << static_cast<void*>(p) << "/" << plen << " overlaps following "
×
151
                                                << static_cast<void*>(after->first));
152
               }
153
            }
154
         }
155
      } else if(op == 1) {
248,119✔
156
         if(ptrs.empty()) {
248,119✔
157
            continue;
248,119✔
158
         }
159

160
         size_t which_ptr = idx % ptrs.size();
×
161

162
         auto itr = ptrs.begin();
×
163

164
         while(which_ptr-- > 0) {
×
165
            ++itr;
×
166
         }
167

168
         //printf("free %p %d\n", itr->first, itr->second);
169
         FUZZER_ASSERT_TRUE(pool.deallocate(itr->first, itr->second));
×
170
         ptrs.erase(itr);
×
171
      }
172
   }
173
}
1,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