Warning, file /libraries/qca/src/botantools/botan/alloc_mmap/mmap_mem.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 Copyright (C) 1999-2007 The Botan Project. All rights reserved.
0003 
0004 Redistribution and use in source and binary forms, for any use, with or without
0005 modification, is permitted provided that the following conditions are met:
0006 
0007 1. Redistributions of source code must retain the above copyright notice, this
0008 list of conditions, and the following disclaimer.
0009 
0010 2. Redistributions in binary form must reproduce the above copyright notice,
0011 this list of conditions, and the following disclaimer in the documentation
0012 and/or other materials provided with the distribution.
0013 
0014 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
0015 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0016 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
0017 
0018 IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
0019 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
0020 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0021 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0022 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0023 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0024 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 */
0026 // LICENSEHEADER_END
0027 namespace QCA { // WRAPNS_LINE
0028 /*************************************************
0029  * Memory Mapping Allocator Source File           *
0030  * (C) 1999-2007 The Botan Project                *
0031  *************************************************/
0032 
0033 } // WRAPNS_LINE
0034 #include <botan/mmap_mem.h>
0035 namespace QCA { // WRAPNS_LINE
0036 } // WRAPNS_LINE
0037 #include <cstring>
0038 namespace QCA { // WRAPNS_LINE
0039 
0040 #ifndef _XOPEN_SOURCE
0041 #define _XOPEN_SOURCE 500
0042 #endif
0043 
0044 #ifndef _XOPEN_SOURCE_EXTENDED
0045 #define _XOPEN_SOURCE_EXTENDED 1
0046 #endif
0047 
0048 } // WRAPNS_LINE
0049 #include <sys/types.h>
0050 namespace QCA { // WRAPNS_LINE
0051 } // WRAPNS_LINE
0052 #include <sys/mman.h>
0053 namespace QCA { // WRAPNS_LINE
0054 } // WRAPNS_LINE
0055 #include <sys/stat.h>
0056 namespace QCA { // WRAPNS_LINE
0057 } // WRAPNS_LINE
0058 #include <unistd.h>
0059 namespace QCA { // WRAPNS_LINE
0060 } // WRAPNS_LINE
0061 #include <cstdlib>
0062 namespace QCA { // WRAPNS_LINE
0063 } // WRAPNS_LINE
0064 #include <fcntl.h>
0065 namespace QCA { // WRAPNS_LINE
0066 
0067 #ifndef MAP_FAILED
0068 #define MAP_FAILED -1
0069 #endif
0070 
0071 namespace Botan {
0072 
0073 namespace {
0074 
0075 /*************************************************
0076  * MemoryMapping_Allocator Exception              *
0077  *************************************************/
0078 class MemoryMapping_Failed : public Exception
0079 {
0080 public:
0081     MemoryMapping_Failed(const std::string &msg)
0082         : Exception("MemoryMapping_Allocator: " + msg)
0083     {
0084     }
0085 };
0086 
0087 }
0088 
0089 /*************************************************
0090  * Memory Map a File into Memory                  *
0091  *************************************************/
0092 void *MemoryMapping_Allocator::alloc_block(u32bit n)
0093 {
0094     class TemporaryFile
0095     {
0096     public:
0097         int get_fd() const
0098         {
0099             return fd;
0100         }
0101         const std::string path() const
0102         {
0103             return filepath;
0104         }
0105 
0106         TemporaryFile(const std::string &base)
0107         {
0108             const std::string path = base + "XXXXXX";
0109 
0110             filepath = new char[path.length() + 1];
0111             std::strcpy(filepath, path.c_str());
0112 
0113             mode_t old_umask = umask(077);
0114             fd               = mkstemp(filepath);
0115             umask(old_umask);
0116         }
0117 
0118         ~TemporaryFile() QCA_NOEXCEPT(false)
0119         {
0120             delete[] filepath;
0121             if (fd != -1 && close(fd) == -1)
0122                 throw MemoryMapping_Failed("Could not close file");
0123         }
0124 
0125         TemporaryFile(const TemporaryFile &)            = delete;
0126         TemporaryFile &operator=(const TemporaryFile &) = delete;
0127 
0128     private:
0129         int   fd;
0130         char *filepath;
0131     };
0132 
0133     TemporaryFile file("/tmp/botan_");
0134 
0135     if (file.get_fd() == -1)
0136         throw MemoryMapping_Failed("Could not create file");
0137 
0138     if (unlink(file.path().c_str()))
0139         throw MemoryMapping_Failed("Could not unlink file " + file.path());
0140 
0141     lseek(file.get_fd(), n - 1, SEEK_SET);
0142     if (write(file.get_fd(), "\0", 1) != 1)
0143         throw MemoryMapping_Failed("Could not write to file");
0144 
0145     void *ptr = mmap(nullptr, n, PROT_READ | PROT_WRITE, MAP_SHARED, file.get_fd(), 0);
0146 
0147     if (ptr == (void *)MAP_FAILED)
0148         throw MemoryMapping_Failed("Could not map file");
0149 
0150     return ptr;
0151 }
0152 
0153 /*************************************************
0154  * Remove a Memory Mapping                        *
0155  *************************************************/
0156 void MemoryMapping_Allocator::dealloc_block(void *ptr, u32bit n)
0157 {
0158     if (ptr == nullptr)
0159         return;
0160 #ifdef MLOCK_NOT_VOID_PTR
0161 #define MLOCK_TYPE_CAST (char *)
0162 #else
0163 #define MLOCK_TYPE_CAST
0164 #endif
0165 
0166     const u32bit OVERWRITE_PASSES = 12;
0167     const byte   PATTERNS[]       = {
0168         0x00, 0xFF, 0xAA, 0x55, 0x73, 0x8C, 0x5F, 0xA0, 0x6E, 0x91, 0x30, 0xCF, 0xD3, 0x2C, 0xAC, 0x53};
0169 
0170     for (u32bit j = 0; j != OVERWRITE_PASSES; j++) {
0171         std::memset(ptr, PATTERNS[j % sizeof(PATTERNS)], n);
0172         if (msync(MLOCK_TYPE_CAST ptr, n, MS_SYNC))
0173             throw MemoryMapping_Failed("Sync operation failed");
0174     }
0175     std::memset(ptr, 0, n);
0176     if (msync(MLOCK_TYPE_CAST ptr, n, MS_SYNC))
0177         throw MemoryMapping_Failed("Sync operation failed");
0178 
0179     if (munmap(MLOCK_TYPE_CAST ptr, n))
0180         throw MemoryMapping_Failed("Could not unmap file");
0181 }
0182 
0183 }
0184 } // WRAPNS_LINE