1/*
2Copyright (C) 1999-2007 The Botan Project. All rights reserved.
3
4Redistribution and use in source and binary forms, for any use, with or without
5modification, is permitted provided that the following conditions are met:
6
71. Redistributions of source code must retain the above copyright notice, this
8list of conditions, and the following disclaimer.
9
102. Redistributions in binary form must reproduce the above copyright notice,
11this list of conditions, and the following disclaimer in the documentation
12and/or other materials provided with the distribution.
13
14THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
17
18IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26// LICENSEHEADER_END
27namespace QCA { // WRAPNS_LINE
28/*************************************************
29 * Memory Mapping Allocator Source File *
30 * (C) 1999-2007 The Botan Project *
31 *************************************************/
32
33} // WRAPNS_LINE
34#include <botan/mmap_mem.h>
35namespace QCA { // WRAPNS_LINE
36} // WRAPNS_LINE
37#include <cstring>
38namespace QCA { // WRAPNS_LINE
39
40#ifndef _XOPEN_SOURCE
41#define _XOPEN_SOURCE 500
42#endif
43
44#ifndef _XOPEN_SOURCE_EXTENDED
45#define _XOPEN_SOURCE_EXTENDED 1
46#endif
47
48} // WRAPNS_LINE
49#include <sys/types.h>
50namespace QCA { // WRAPNS_LINE
51} // WRAPNS_LINE
52#include <sys/mman.h>
53namespace QCA { // WRAPNS_LINE
54} // WRAPNS_LINE
55#include <sys/stat.h>
56namespace QCA { // WRAPNS_LINE
57} // WRAPNS_LINE
58#include <unistd.h>
59namespace QCA { // WRAPNS_LINE
60} // WRAPNS_LINE
61#include <cstdlib>
62namespace QCA { // WRAPNS_LINE
63} // WRAPNS_LINE
64#include <fcntl.h>
65namespace QCA { // WRAPNS_LINE
66
67#ifndef MAP_FAILED
68#define MAP_FAILED -1
69#endif
70
71namespace Botan {
72
73namespace {
74
75/*************************************************
76 * MemoryMapping_Allocator Exception *
77 *************************************************/
78class MemoryMapping_Failed : public Exception
79{
80public:
81 MemoryMapping_Failed(const std::string &msg)
82 : Exception("MemoryMapping_Allocator: " + msg)
83 {
84 }
85};
86
87}
88
89/*************************************************
90 * Memory Map a File into Memory *
91 *************************************************/
92void *MemoryMapping_Allocator::alloc_block(u32bit n)
93{
94 class TemporaryFile
95 {
96 public:
97 int get_fd() const
98 {
99 return fd;
100 }
101 const std::string path() const
102 {
103 return filepath;
104 }
105
106 TemporaryFile(const std::string &base)
107 {
108 const std::string path = base + "XXXXXX";
109
110 filepath = new char[path.length() + 1];
111 std::strcpy(dest: filepath, src: path.c_str());
112
113 mode_t old_umask = umask(mask: 077);
114 fd = mkstemp(template: filepath);
115 umask(mask: old_umask);
116 }
117
118 ~TemporaryFile() QCA_NOEXCEPT(false)
119 {
120 delete[] filepath;
121 if (fd != -1 && close(fd: fd) == -1)
122 throw MemoryMapping_Failed("Could not close file");
123 }
124
125 TemporaryFile(const TemporaryFile &) = delete;
126 TemporaryFile &operator=(const TemporaryFile &) = delete;
127
128 private:
129 int fd;
130 char *filepath;
131 };
132
133 TemporaryFile file("/tmp/botan_");
134
135 if (file.get_fd() == -1)
136 throw MemoryMapping_Failed("Could not create file");
137
138 if (unlink(name: file.path().c_str()))
139 throw MemoryMapping_Failed("Could not unlink file " + file.path());
140
141 lseek(fd: file.get_fd(), offset: n - 1, SEEK_SET);
142 if (write(fd: file.get_fd(), buf: "\0", n: 1) != 1)
143 throw MemoryMapping_Failed("Could not write to file");
144
145 void *ptr = mmap(addr: nullptr, len: n, PROT_READ | PROT_WRITE, MAP_SHARED, fd: file.get_fd(), offset: 0);
146
147 if (ptr == (void *)MAP_FAILED)
148 throw MemoryMapping_Failed("Could not map file");
149
150 return ptr;
151}
152
153/*************************************************
154 * Remove a Memory Mapping *
155 *************************************************/
156void MemoryMapping_Allocator::dealloc_block(void *ptr, u32bit n)
157{
158 if (ptr == nullptr)
159 return;
160#ifdef MLOCK_NOT_VOID_PTR
161#define MLOCK_TYPE_CAST (char *)
162#else
163#define MLOCK_TYPE_CAST
164#endif
165
166 const u32bit OVERWRITE_PASSES = 12;
167 const byte PATTERNS[] = {
168 0x00, 0xFF, 0xAA, 0x55, 0x73, 0x8C, 0x5F, 0xA0, 0x6E, 0x91, 0x30, 0xCF, 0xD3, 0x2C, 0xAC, 0x53};
169
170 for (u32bit j = 0; j != OVERWRITE_PASSES; j++) {
171 std::memset(s: ptr, c: PATTERNS[j % sizeof(PATTERNS)], n: n);
172 if (msync(MLOCK_TYPE_CAST addr: ptr, len: n, MS_SYNC))
173 throw MemoryMapping_Failed("Sync operation failed");
174 }
175 std::memset(s: ptr, c: 0, n: n);
176 if (msync(MLOCK_TYPE_CAST addr: ptr, len: n, MS_SYNC))
177 throw MemoryMapping_Failed("Sync operation failed");
178
179 if (munmap(MLOCK_TYPE_CAST addr: ptr, len: n))
180 throw MemoryMapping_Failed("Could not unmap file");
181}
182
183}
184} // WRAPNS_LINE
185

source code of qca/src/botantools/botan/alloc_mmap/mmap_mem.cpp