[IOT-1519] Securely zero buffers containing secret data
[platform/upstream/iotivity.git] / resource / c_common / oic_malloc / src / oic_malloc.c
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 //-----------------------------------------------------------------------------
22 // Includes
23 //-----------------------------------------------------------------------------
24 #include <stdlib.h>
25 #include "oic_malloc.h"
26
27 #include "iotivity_config.h"
28
29 #ifdef HAVE_WINDOWS_H
30 #include <windows.h>
31 #endif
32
33 // Enable extra debug logging for malloc.  Comment out to disable
34 #ifdef ENABLE_MALLOC_DEBUG
35 #include "logger.h"
36 #define TAG "OIC_MALLOC"
37 #endif
38
39 //-----------------------------------------------------------------------------
40 // Typedefs
41 //-----------------------------------------------------------------------------
42
43 //-----------------------------------------------------------------------------
44 // Private variables
45 //-----------------------------------------------------------------------------
46
47 //-----------------------------------------------------------------------------
48 // Macros
49 //-----------------------------------------------------------------------------
50
51 //-----------------------------------------------------------------------------
52 // Internal API function
53 //-----------------------------------------------------------------------------
54
55 //-----------------------------------------------------------------------------
56 // Private internal function prototypes
57 //-----------------------------------------------------------------------------
58
59 //-----------------------------------------------------------------------------
60 // Public APIs
61 //-----------------------------------------------------------------------------
62 #ifdef ENABLE_MALLOC_DEBUG
63 static uint32_t count;
64 #endif
65
66 void *OICMalloc(size_t size)
67 {
68     if (0 == size)
69     {
70         return NULL;
71     }
72
73 #ifdef ENABLE_MALLOC_DEBUG
74     void *ptr = malloc(size);
75     if (ptr)
76     {
77         count++;
78     }
79     OIC_LOG_V(INFO, TAG, "malloc: ptr=%p, size=%u, count=%u", ptr, size, count);
80     return ptr;
81 #else
82     return malloc(size);
83 #endif
84 }
85
86 void *OICCalloc(size_t num, size_t size)
87 {
88     if (0 == size || 0 == num)
89     {
90         return NULL;
91     }
92
93 #ifdef ENABLE_MALLOC_DEBUG
94     void *ptr = calloc(num, size);
95     if (ptr)
96     {
97         count++;
98     }
99     OIC_LOG_V(INFO, TAG, "calloc: ptr=%p, num=%u, size=%u, count=%u", ptr, num, size, count);
100     return ptr;
101 #else
102     return calloc(num, size);
103 #endif
104 }
105
106 void *OICRealloc(void* ptr, size_t size)
107 {
108     // Override realloc() behavior for NULL pointer which normally would
109     // work as per malloc(), however we suppress the behavior of possibly
110     // returning a non-null unique pointer.
111     if (ptr == NULL)
112     {
113         return OICMalloc(size);
114     }
115
116     // Otherwise leave the behavior up to realloc() itself:
117
118 #ifdef ENABLE_MALLOC_DEBUG
119     void* newptr = realloc(ptr, size);
120     OIC_LOG_V(INFO, TAG, "realloc: ptr=%p, newptr=%p, size=%u", ptr, newptr, size);
121     // Very important to return the correct pointer here, as it only *somtimes*
122     // differs and thus can be hard to notice/test:
123     return newptr;
124 #else
125     return realloc(ptr, size);
126 #endif
127 }
128
129 void OICFree(void *ptr)
130 {
131 #ifdef ENABLE_MALLOC_DEBUG
132     // Since OICMalloc() did not increment count if it returned NULL,
133     // guard the decrement:
134     if (ptr)
135     {
136         count--;
137     }
138     OIC_LOG_V(INFO, TAG, "free: ptr=%p, count=%u", ptr, count);
139 #endif
140
141     free(ptr);
142 }
143
144 void OICClearMemory(void *buf, size_t n)
145 {
146     if (NULL != buf) {
147 #ifdef HAVE_WINDOWS_H
148         SecureZeroMemory(buf, n);
149 #else
150         volatile unsigned char* p = (volatile unsigned char*)buf;
151         while (n--)
152         {
153             *p++ = 0;
154         }
155 #endif
156     }
157 }