summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/mem.c
diff options
context:
space:
mode:
authorbeck <>2000-03-19 11:13:58 +0000
committerbeck <>2000-03-19 11:13:58 +0000
commit796d609550df3a33fc11468741c5d2f6d3df4c11 (patch)
tree6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libcrypto/mem.c
parent5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff)
downloadopenbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.gz
openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.bz2
openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.zip
OpenSSL 0.9.5 merge
*warning* this bumps shared lib minors for libssl and libcrypto from 2.1 to 2.2 if you are using the ssl26 packages for ssh and other things to work you will need to get new ones (see ~beck/libsslsnap/<arch>) on cvs or ~beck/src-patent.tar.gz on cvs
Diffstat (limited to 'src/lib/libcrypto/mem.c')
-rw-r--r--src/lib/libcrypto/mem.c432
1 files changed, 132 insertions, 300 deletions
diff --git a/src/lib/libcrypto/mem.c b/src/lib/libcrypto/mem.c
index 61fc1e184e..5a661e5f45 100644
--- a/src/lib/libcrypto/mem.c
+++ b/src/lib/libcrypto/mem.c
@@ -59,371 +59,203 @@
59#include <stdio.h> 59#include <stdio.h>
60#include <stdlib.h> 60#include <stdlib.h>
61#include <openssl/crypto.h> 61#include <openssl/crypto.h>
62#ifdef CRYPTO_MDEBUG_TIME
63# include <time.h>
64#endif
65#include <openssl/buffer.h>
66#include <openssl/bio.h>
67#include <openssl/lhash.h>
68#include "cryptlib.h" 62#include "cryptlib.h"
69 63
70/* #ifdef CRYPTO_MDEBUG */
71/* static int mh_mode=CRYPTO_MEM_CHECK_ON; */
72/* #else */
73static int mh_mode=CRYPTO_MEM_CHECK_OFF;
74/* #endif */
75/* State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
76 * thinks that certain allocations should not be checked (e.g. the data
77 * structures used for memory checking). It is not suitable as an initial
78 * state: the library will unexpectedly enable memory checking when it
79 * executes one of those sections that want to disable checking
80 * temporarily.
81 *
82 * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
83 */
84
85static unsigned long order=0;
86
87static LHASH *mh=NULL;
88 64
89typedef struct mem_st 65static int allow_customize = 1; /* we provide flexible functions for */
90 { 66static int allow_customize_debug = 1;/* exchanging memory-related functions at
91 char *addr; 67 * run-time, but this must be done
92 int num; 68 * before any blocks are actually
93 const char *file; 69 * allocated; or we'll run into huge
94 int line; 70 * problems when malloc/free pairs
95#ifdef CRYPTO_MDEBUG_THREAD 71 * don't match etc. */
96 unsigned long thread; 72
73/* may be changed as long as `allow_customize' is set */
74static void *(*malloc_locked_func)(size_t) = malloc;
75static void (*free_locked_func)(void *) = free;
76static void *(*malloc_func)(size_t) = malloc;
77static void *(*realloc_func)(void *, size_t)= realloc;
78static void (*free_func)(void *) = free;
79
80/* may be changed as long as `allow_customize_debug' is set */
81/* XXX use correct function pointer types */
82#ifdef CRYPTO_MDEBUG
83 /* use default functions from mem_dbg.c */
84 static void (*malloc_debug_func)()= (void (*)())CRYPTO_dbg_malloc;
85 static void (*realloc_debug_func)()= (void (*)())CRYPTO_dbg_realloc;
86 static void (*free_debug_func)()= (void (*)())CRYPTO_dbg_free;
87 static void (*set_debug_options_func)()= (void (*)())CRYPTO_dbg_set_options;
88 static long (*get_debug_options_func)()= (long (*)())CRYPTO_dbg_get_options;
89#else
90 /* applications can use CRYPTO_malloc_debug_init() to select above case
91 * at run-time */
92 static void (*malloc_debug_func)()= NULL;
93 static void (*realloc_debug_func)()= NULL;
94 static void (*free_debug_func)()= NULL;
95 static void (*set_debug_options_func)()= NULL;
96 static long (*get_debug_options_func)()= NULL;
97#endif 97#endif
98 unsigned long order;
99#ifdef CRYPTO_MDEBUG_TIME
100 time_t time;
101#endif
102 } MEM;
103
104int CRYPTO_mem_ctrl(int mode)
105 {
106 int ret=mh_mode;
107
108 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
109 switch (mode)
110 {
111 /* for applications: */
112 case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
113 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
114 break;
115 case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
116 mh_mode = 0;
117 break;
118 98
119 /* switch off temporarily (for library-internal use): */
120 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
121 mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE;
122 break;
123 case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
124 if (mh_mode&CRYPTO_MEM_CHECK_ON)
125 mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
126 break;
127 99
128 default: 100int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
129 break; 101 void (*f)(void *))
130 }
131 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
132 return(ret);
133 }
134
135static int mem_cmp(MEM *a, MEM *b)
136 {
137 return(a->addr - b->addr);
138 }
139
140static unsigned long mem_hash(MEM *a)
141 { 102 {
142 unsigned long ret; 103 if (!allow_customize)
143 104 return 0;
144 ret=(unsigned long)a->addr; 105 if ((m == NULL) || (r == NULL) || (f == NULL))
145 106 return 0;
146 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
147 return(ret);
148 }
149
150static char *(*malloc_locked_func)()=(char *(*)())malloc;
151static void (*free_locked_func)()=(void (*)())free;
152static char *(*malloc_func)()= (char *(*)())malloc;
153static char *(*realloc_func)()= (char *(*)())realloc;
154static void (*free_func)()= (void (*)())free;
155
156void CRYPTO_set_mem_functions(char *(*m)(), char *(*r)(), void (*f)())
157 {
158 if ((m == NULL) || (r == NULL) || (f == NULL)) return;
159 malloc_func=m; 107 malloc_func=m;
160 realloc_func=r; 108 realloc_func=r;
161 free_func=f; 109 free_func=f;
162 malloc_locked_func=m; 110 malloc_locked_func=m;
163 free_locked_func=f; 111 free_locked_func=f;
112 return 1;
164 } 113 }
165 114
166void CRYPTO_set_locked_mem_functions(char *(*m)(), void (*f)()) 115int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *))
167 { 116 {
168 if ((m == NULL) || (f == NULL)) return; 117 if (!allow_customize)
118 return 0;
119 if ((m == NULL) || (f == NULL))
120 return 0;
169 malloc_locked_func=m; 121 malloc_locked_func=m;
170 free_locked_func=f; 122 free_locked_func=f;
123 return 1;
124 }
125
126int CRYPTO_set_mem_debug_functions(void (*m)(), void (*r)(), void (*f)(),void (*so)(),long (*go)())
127 {
128 if (!allow_customize_debug)
129 return 0;
130 malloc_debug_func=m;
131 realloc_debug_func=r;
132 free_debug_func=f;
133 set_debug_options_func=so;
134 get_debug_options_func=go;
135 return 1;
171 } 136 }
172 137
173void CRYPTO_get_mem_functions(char *(**m)(), char *(**r)(), void (**f)()) 138void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
139 void (**f)(void *))
174 { 140 {
175 if (m != NULL) *m=malloc_func; 141 if (m != NULL) *m=malloc_func;
176 if (r != NULL) *r=realloc_func; 142 if (r != NULL) *r=realloc_func;
177 if (f != NULL) *f=free_func; 143 if (f != NULL) *f=free_func;
178 } 144 }
179 145
180void CRYPTO_get_locked_mem_functions(char *(**m)(), void (**f)()) 146void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *))
181 { 147 {
182 if (m != NULL) *m=malloc_locked_func; 148 if (m != NULL) *m=malloc_locked_func;
183 if (f != NULL) *f=free_locked_func; 149 if (f != NULL) *f=free_locked_func;
184 } 150 }
185 151
186void *CRYPTO_malloc_locked(int num) 152void CRYPTO_get_mem_debug_functions(void (**m)(), void (**r)(), void (**f)(),void (**so)(),long (**go)())
187 { 153 {
188 return(malloc_locked_func(num)); 154 if (m != NULL) *m=malloc_debug_func;
155 if (r != NULL) *r=realloc_debug_func;
156 if (f != NULL) *f=free_debug_func;
157 if (so != NULL) *so=set_debug_options_func;
158 if (go != NULL) *go=get_debug_options_func;
189 } 159 }
190 160
191void CRYPTO_free_locked(void *str)
192 {
193 free_locked_func(str);
194 }
195 161
196void *CRYPTO_malloc(int num) 162void *CRYPTO_malloc_locked(int num, const char *file, int line)
197 { 163 {
198 return(malloc_func(num)); 164 char *ret = NULL;
199 }
200 165
201void *CRYPTO_realloc(void *str, int num) 166 allow_customize = 0;
202 { 167 if (malloc_debug_func != NULL)
203 return(realloc_func(str,num));
204 }
205
206void CRYPTO_free(void *str)
207 {
208 free_func(str);
209 }
210
211static unsigned long break_order_num=0;
212void *CRYPTO_dbg_malloc(int num, const char *file, int line)
213 {
214 char *ret;
215 MEM *m,*mm;
216
217 if ((ret=malloc_func(num)) == NULL)
218 return(NULL);
219
220 if (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
221 { 168 {
222 MemCheck_off(); 169 allow_customize_debug = 0;
223 if ((m=(MEM *)Malloc(sizeof(MEM))) == NULL) 170 malloc_debug_func(NULL, num, file, line, 0);
224 {
225 Free(ret);
226 MemCheck_on();
227 return(NULL);
228 }
229 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
230 if (mh == NULL)
231 {
232 if ((mh=lh_new(mem_hash,mem_cmp)) == NULL)
233 {
234 Free(ret);
235 Free(m);
236 ret=NULL;
237 goto err;
238 }
239 }
240
241 m->addr=ret;
242 m->file=file;
243 m->line=line;
244 m->num=num;
245#ifdef CRYPTO_MDEBUG_THREAD
246 m->thread=CRYPTO_thread_id();
247#endif
248 if (order == break_order_num)
249 {
250 /* BREAK HERE */
251 m->order=order;
252 }
253 m->order=order++;
254#ifdef CRYPTO_MDEBUG_TIME
255 m->time=time(NULL);
256#endif
257 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
258 {
259 /* Not good, but don't sweat it */
260 Free(mm);
261 }
262err:
263 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
264 MemCheck_on();
265 } 171 }
266 return(ret); 172 ret = malloc_locked_func(num);
173#ifdef LEVITTE_DEBUG
174 fprintf(stderr, "LEVITTE_DEBUG: > 0x%p (%d)\n", ret, num);
175#endif
176 if (malloc_debug_func != NULL)
177 malloc_debug_func(ret, num, file, line, 1);
178
179 return ret;
267 } 180 }
268 181
269void CRYPTO_dbg_free(void *addr) 182void CRYPTO_free_locked(void *str)
270 { 183 {
271 MEM m,*mp; 184 if (free_debug_func != NULL)
272 185 free_debug_func(str, 0);
273 if ((mh_mode & CRYPTO_MEM_CHECK_ENABLE) && (mh != NULL)) 186#ifdef LEVITTE_DEBUG
274 { 187 fprintf(stderr, "LEVITTE_DEBUG: < 0x%p\n", str);
275 MemCheck_off(); 188#endif
276 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); 189 free_locked_func(str);
277 m.addr=addr; 190 if (free_debug_func != NULL)
278 mp=(MEM *)lh_delete(mh,(char *)&m); 191 free_debug_func(NULL, 1);
279 if (mp != NULL)
280 Free(mp);
281 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
282 MemCheck_on();
283 }
284 free_func(addr);
285 } 192 }
286 193
287void *CRYPTO_dbg_realloc(void *addr, int num, const char *file, int line) 194void *CRYPTO_malloc(int num, const char *file, int line)
288 { 195 {
289 char *ret; 196 char *ret = NULL;
290 MEM m,*mp;
291
292 ret=realloc_func(addr,num);
293 if (ret == addr) return(ret);
294 197
295 if (mh_mode & CRYPTO_MEM_CHECK_ENABLE) 198 allow_customize = 0;
199 if (malloc_debug_func != NULL)
296 { 200 {
297 MemCheck_off(); 201 allow_customize_debug = 0;
298 if (ret == NULL) return(NULL); 202 malloc_debug_func(NULL, num, file, line, 0);
299 m.addr=addr;
300 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
301 mp=(MEM *)lh_delete(mh,(char *)&m);
302 if (mp != NULL)
303 {
304 mp->addr=ret;
305 lh_insert(mh,(char *)mp);
306 }
307 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
308 MemCheck_on();
309 } 203 }
310 return(ret); 204 ret = malloc_func(num);
311 } 205#ifdef LEVITTE_DEBUG
312 206 fprintf(stderr, "LEVITTE_DEBUG: > 0x%p (%d)\n", ret, num);
313void *CRYPTO_remalloc(void *a, int n) 207#endif
314 { 208 if (malloc_debug_func != NULL)
315 if (a != NULL) Free(a); 209 malloc_debug_func(ret, num, file, line, 1);
316 a=(char *)Malloc(n);
317 return(a);
318 }
319 210
320void *CRYPTO_dbg_remalloc(void *a, int n, const char *file, int line) 211 return ret;
321 {
322 if (a != NULL) CRYPTO_dbg_free(a);
323 a=(char *)CRYPTO_dbg_malloc(n,file,line);
324 return(a);
325 } 212 }
326 213
327 214void *CRYPTO_realloc(void *str, int num, const char *file, int line)
328typedef struct mem_leak_st
329 { 215 {
330 BIO *bio; 216 char *ret = NULL;
331 int chunks;
332 long bytes;
333 } MEM_LEAK;
334 217
335static void print_leak(MEM *m, MEM_LEAK *l) 218 if (realloc_debug_func != NULL)
336 { 219 realloc_debug_func(str, NULL, num, file, line, 0);
337 char buf[128]; 220 ret = realloc_func(str,num);
338#ifdef CRYPTO_MDEBUG_TIME 221#ifdef LEVITTE_DEBUG
339 struct tm *lcl; 222 fprintf(stderr, "LEVITTE_DEBUG: | 0x%p -> 0x%p (%d)\n", str, ret, num);
340#endif 223#endif
224 if (realloc_debug_func != NULL)
225 realloc_debug_func(str, ret, num, file, line, 1);
341 226
342 if(m->addr == (char *)l->bio) 227 return ret;
343 return;
344
345#ifdef CRYPTO_MDEBUG_TIME
346 lcl = localtime(&m->time);
347#endif
348
349 sprintf(buf,
350#ifdef CRYPTO_MDEBUG_TIME
351 "[%02d:%02d:%02d] "
352#endif
353 "%5lu file=%s, line=%d, "
354#ifdef CRYPTO_MDEBUG_THREAD
355 "thread=%lu, "
356#endif
357 "number=%d, address=%08lX\n",
358#ifdef CRYPTO_MDEBUG_TIME
359 lcl->tm_hour,lcl->tm_min,lcl->tm_sec,
360#endif
361 m->order,m->file,m->line,
362#ifdef CRYPTO_MDEBUG_THREAD
363 m->thread,
364#endif
365 m->num,(unsigned long)m->addr);
366
367 BIO_puts(l->bio,buf);
368 l->chunks++;
369 l->bytes+=m->num;
370 } 228 }
371 229
372void CRYPTO_mem_leaks(BIO *b) 230void CRYPTO_free(void *str)
373 { 231 {
374 MEM_LEAK ml; 232 if (free_debug_func != NULL)
375 char buf[80]; 233 free_debug_func(str, 0);
376 234#ifdef LEVITTE_DEBUG
377 if (mh == NULL) return; 235 fprintf(stderr, "LEVITTE_DEBUG: < 0x%p\n", str);
378 ml.bio=b;
379 ml.bytes=0;
380 ml.chunks=0;
381 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
382 lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml);
383 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
384 if (ml.chunks != 0)
385 {
386 sprintf(buf,"%ld bytes leaked in %d chunks\n",
387 ml.bytes,ml.chunks);
388 BIO_puts(b,buf);
389 }
390
391#if 0
392 lh_stats_bio(mh,b);
393 lh_node_stats_bio(mh,b);
394 lh_node_usage_stats_bio(mh,b);
395#endif 236#endif
237 free_func(str);
238 if (free_debug_func != NULL)
239 free_debug_func(NULL, 1);
396 } 240 }
397 241
398static void (*mem_cb)()=NULL; 242void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
399
400static void cb_leak(MEM *m, char *cb)
401 { 243 {
402 void (*mem_callback)()=(void (*)())cb; 244 if (a != NULL) Free(a);
403 mem_callback(m->order,m->file,m->line,m->num,m->addr); 245 a=(char *)Malloc(num);
246 return(a);
404 } 247 }
405 248
406void CRYPTO_mem_leaks_cb(void (*cb)()) 249
250void CRYPTO_set_mem_debug_options(long bits)
407 { 251 {
408 if (mh == NULL) return; 252 if (set_debug_options_func != NULL)
409 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); 253 set_debug_options_func(bits);
410 mem_cb=cb;
411 lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
412 mem_cb=NULL;
413 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
414 } 254 }
415 255
416#ifndef NO_FP_API 256long CRYPTO_get_mem_debug_options(void)
417void CRYPTO_mem_leaks_fp(FILE *fp)
418 { 257 {
419 BIO *b; 258 if (get_debug_options_func != NULL)
420 259 return get_debug_options_func();
421 if (mh == NULL) return; 260 return 0;
422 if ((b=BIO_new(BIO_s_file())) == NULL)
423 return;
424 BIO_set_fp(b,fp,BIO_NOCLOSE);
425 CRYPTO_mem_leaks(b);
426 BIO_free(b);
427 } 261 }
428#endif
429