jaulib v1.3.0
Jau Support Library (C++, Java, ..)
callocator_sec.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2022 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef C_ALLOCATOR_SEC_HPP
26#define C_ALLOCATOR_SEC_HPP
27
28#include <cinttypes>
29#include <memory>
30#include <cstring>
31
32#include <jau/basic_types.hpp>
33
34namespace jau {
35
36/**
37 * A simple secure allocator for integral types using POSIX C functions: <code>::malloc()</code> and <code>::free()</code>.
38 *
39 * callocator_sec is similar to callocator, but
40 * - only works for integral types
41 * - deallocate explicitly bzero's the memory before free for secure scrubbing.
42 * - dropped realloc() for security reasons, since realloc() could free old memory block w/o scrubbing.
43 *
44 * This class shall be compliant with <i>C++ named requirements for Allocator</i>.
45 *
46 * Not implementing deprecated (C++17) and removed (C++20)
47 * methods: address(), max_size(), construct() and destroy().
48 */
49template <typename T,
50 std::enable_if_t< std::is_integral_v<T>, bool> = true>
52{
53 public:
54 // typedefs' for C++ named requirements: Allocator
55 typedef T value_type;
56 typedef std::size_t size_type;
57 typedef std::ptrdiff_t difference_type;
59
60 // C++17, deprecated in C++20
61 typedef std::true_type is_always_equal;
62
63 // deprecated in C++17 and removed in C++20
64 typedef T* pointer;
65 typedef const T* const_pointer;
66 typedef T& reference;
67 typedef const T& const_reference;
68 template <class U> struct rebind {typedef callocator_sec<U> other;};
69
70 private:
71 typedef std::remove_const_t<T> value_type_mutable;
72 /** Required to create and move immutable elements, aka const */
73 typedef value_type_mutable* pointer_mutable;
74
75 public:
76 callocator_sec() noexcept = default; // C++11
77
78#if __cplusplus > 201703L
79 constexpr callocator_sec(const callocator_sec&) noexcept // NOLINT(modernize-use-equals-default)
80 {} // C++20
81#else
82 callocator_sec(const callocator_sec&) noexcept // NOLINT(modernize-use-equals-default)
83 { }
84#endif
85
86#if __cplusplus > 201703L
87 template <typename U>
88 constexpr callocator_sec(const callocator_sec<U>&) noexcept // NOLINT(modernize-use-equals-default)
89 { } // C++20
90#else
91 template <typename U>
92 callocator_sec(const callocator_sec<U>&) noexcept // NOLINT(modernize-use-equals-default)
93 { }
94#endif
95
96#if __cplusplus > 201703L
97 constexpr ~callocator_sec() = default; // C++20
98#else
99 ~callocator_sec() = default;
100#endif
101
102#if __cplusplus <= 201703L
103 value_type* allocate(std::size_t n, const void*) { // C++17 deprecated; C++20 removed
104 return reinterpret_cast<value_type*>( ::malloc( n * sizeof(value_type) ) );
105 }
106#endif
107
108#if __cplusplus > 201703L
109 [[nodiscard]] constexpr value_type* allocate(std::size_t n) { // C++20
110 return reinterpret_cast<value_type*>( ::malloc( n * sizeof(value_type) ) );
111 }
112#else
113 value_type* allocate(std::size_t n) { // C++17
114 return reinterpret_cast<value_type*>( ::malloc( n * sizeof(value_type) ) );
115 }
116#endif
117
118#if __cplusplus > 201703L
119 constexpr void deallocate(value_type* p, std::size_t n ) {
120 ::explicit_bzero(p, n); // non-optomized away bzero
121 ::free( reinterpret_cast<void*>( const_cast<pointer_mutable>(p) ) );
122 }
123#else
124 void deallocate(value_type* p, std::size_t n ) {
125 ::explicit_bzero(p, n); // non-optomized away bzero
126 ::free( reinterpret_cast<void*>( const_cast<pointer_mutable>(p) ) );
127 }
128#endif
129
130};
131
132
133#if __cplusplus > 201703L
134template <class T1, class T2>
135 constexpr bool operator==(const callocator_sec<T1>& lhs, const callocator_sec<T2>& rhs) noexcept {
136#if 0
137 if( &lhs == &rhs ) {
138 return true;
139 }
140 return lhs.memory_usage == rhs.memory_usage;
141#else
142 (void)lhs;
143 (void)rhs;
144 return true;
145#endif
146 }
147#else
148 template <class T1, class T2>
149 bool operator==(const callocator_sec<T1>& lhs, const callocator_sec<T2>& rhs) noexcept {
150#if 0
151 if( &lhs == &rhs ) {
152 return true;
153 }
154 return lhs.memory_usage == rhs.memory_usage;
155#else
156 (void)lhs;
157 (void)rhs;
158 return true;
159#endif
160 }
161 template <class T1, class T2>
162 bool operator!=(const callocator_sec<T1>& lhs, const callocator_sec<T2>& rhs) noexcept {
163 return !(lhs==rhs);
164 }
165#endif
166
167} /* namespace jau */
168
169#endif // C_ALLOCATOR_SEC_HPP
170
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:150
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:163
callocator_sec< U > other
A simple secure allocator for integral types using POSIX C functions: ::malloc() and ::free().
std::true_type is_always_equal
std::ptrdiff_t difference_type
void deallocate(value_type *p, std::size_t n)
value_type * allocate(std::size_t n)
std::true_type propagate_on_container_move_assignment
callocator_sec(const callocator_sec< U > &) noexcept
~callocator_sec()=default
callocator_sec() noexcept=default
value_type * allocate(std::size_t n, const void *)
callocator_sec(const callocator_sec &) noexcept