• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*############################################################################
2   # Copyright 2016-2017 Intel Corporation
3   #
4   # Licensed under the Apache License, Version 2.0 (the "License");
5   # you may not use this file except in compliance with the License.
6   # You may obtain a copy of the License at
7   #
8   #     http://www.apache.org/licenses/LICENSE-2.0
9   #
10   # Unless required by applicable law or agreed to in writing, software
11   # distributed under the License is distributed on an "AS IS" BASIS,
12   # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   # See the License for the specific language governing permissions and
14   # limitations under the License.
15   ############################################################################*/
16 
17 /*!
18  * \file
19  * \brief Memory access implementation.
20  */
21 
22 #include "epid/common/src/memory.h"
23 
24 #include <stdint.h>
25 #include <string.h>
26 
27 /// Maximum size of the destination buffer
28 #ifndef RSIZE_MAX
29 #define RSIZE_MAX ((SIZE_MAX) >> 1)
30 #endif
31 
32 #ifndef MIN
33 /// Evaluate to minimum of two values
34 #define MIN(a, b) ((a) < (b) ? (a) : (b))
35 #endif  // MIN
36 
37 /// Copies count of character from dest to src
38 /*!  \note Implementation follows C11 memcpy_s but with checks always enabled
39  */
memcpy_S(void * dest,size_t destsz,void const * src,size_t count)40 int memcpy_S(void* dest, size_t destsz, void const* src, size_t count) {
41   size_t i;
42   if (!dest || destsz > RSIZE_MAX) return -1;
43   if (!src || count > RSIZE_MAX || count > destsz ||
44       count > (dest > src ? ((uintptr_t)dest - (uintptr_t)src)
45                           : ((uintptr_t)src - (uintptr_t)dest))) {
46     // zero out dest if error detected
47     memset(dest, 0, destsz);
48     return -1;
49   }
50 
51   for (i = 0; i < count; i++) ((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
52   return 0;
53 }
54 
EpidZeroMemory(void * ptr,size_t size)55 void EpidZeroMemory(void* ptr, size_t size) { memset(ptr, 0, size); }
56 
57 #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
58 
59 #if !defined(EPID_ALLOC_ALIGN)
60 /// Alignment constant for EpidAlloc, must be a power of two
61 #define EPID_ALLOC_ALIGN sizeof(size_t)
62 #endif  // !defined(EPID_ALLOC_ALIGN)
63 
64 #pragma pack(1)
65 /// Allocated memory block information
66 typedef struct EpidAllocHeader {
67   size_t length;  ///< number of bytes memory block is allocated for
68   void* ptr;      ///< pointer to whole memory block including EpidAllocHeader
69 } EpidAllocHeader;
70 #pragma pack()
71 
72 #endif  // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
73 
EpidAlloc(size_t size)74 void* EpidAlloc(size_t size) {
75 #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
76   void* ptr = NULL;
77   if (size <= 0) return NULL;
78   // Allocate memory enough to store size bytes and EpidAllocHeader
79   ptr = calloc(1, size + EPID_ALLOC_ALIGN - 1 + sizeof(EpidAllocHeader));
80   if (ptr) {
81     void* aligned_pointer = (void*)(((uintptr_t)ptr + EPID_ALLOC_ALIGN +
82                                      sizeof(EpidAllocHeader) - 1) &
83                                     (~(EPID_ALLOC_ALIGN - 1)));
84     ((EpidAllocHeader*)aligned_pointer)[-1].length = size;
85     ((EpidAllocHeader*)aligned_pointer)[-1].ptr = ptr;
86     return aligned_pointer;
87   }
88   return NULL;
89 #else  // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
90   return calloc(1, size);
91 #endif  // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
92 }
93 
EpidRealloc(void * ptr,size_t new_size)94 void* EpidRealloc(void* ptr, size_t new_size) {
95 #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
96   void* new_ptr = EpidAlloc(new_size);
97   if (!new_ptr) return NULL;
98   if (ptr) {
99     // Memory copy is used to copy a buffer of variable length
100     if (0 != memcpy_S(new_ptr, ((EpidAllocHeader*)new_ptr)[-1].length, ptr,
101                       MIN(((EpidAllocHeader*)ptr)[-1].length,
102                           ((EpidAllocHeader*)new_ptr)[-1].length))) {
103       EpidFree(new_ptr);
104       return NULL;
105     }
106     EpidFree(ptr);
107   }
108   return new_ptr;
109 #else   // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
110   return realloc(ptr, new_size);
111 #endif  // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
112 }
113 
EpidFree(void * ptr)114 void EpidFree(void* ptr) {
115 #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
116   if (ptr) {
117     EpidZeroMemory(ptr, ((EpidAllocHeader*)ptr)[-1].length);
118     free(((EpidAllocHeader*)ptr)[-1].ptr);
119   }
120 #else   // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
121   free(ptr);
122 #endif  // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
123 }
124