diff options
author | beck <> | 1999-09-29 04:37:45 +0000 |
---|---|---|
committer | beck <> | 1999-09-29 04:37:45 +0000 |
commit | de8f24ea083384bb66b32ec105dc4743c5663cdf (patch) | |
tree | 1412176ae62a3cab2cf2b0b92150fcbceaac6092 /src/lib/libcrypto/mem.c | |
parent | cb929d29896bcb87c2a97417fbd03e50078fc178 (diff) | |
download | openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.gz openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.bz2 openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.zip |
OpenSSL 0.9.4 merge
Diffstat (limited to 'src/lib/libcrypto/mem.c')
-rw-r--r-- | src/lib/libcrypto/mem.c | 228 |
1 files changed, 152 insertions, 76 deletions
diff --git a/src/lib/libcrypto/mem.c b/src/lib/libcrypto/mem.c index 72e501ad0f..61fc1e184e 100644 --- a/src/lib/libcrypto/mem.c +++ b/src/lib/libcrypto/mem.c | |||
@@ -58,12 +58,30 @@ | |||
58 | 58 | ||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include <stdlib.h> | 60 | #include <stdlib.h> |
61 | #include "buffer.h" | 61 | #include <openssl/crypto.h> |
62 | #include "bio.h" | 62 | #ifdef CRYPTO_MDEBUG_TIME |
63 | #include "lhash.h" | 63 | # include <time.h> |
64 | #endif | ||
65 | #include <openssl/buffer.h> | ||
66 | #include <openssl/bio.h> | ||
67 | #include <openssl/lhash.h> | ||
64 | #include "cryptlib.h" | 68 | #include "cryptlib.h" |
65 | 69 | ||
70 | /* #ifdef CRYPTO_MDEBUG */ | ||
71 | /* static int mh_mode=CRYPTO_MEM_CHECK_ON; */ | ||
72 | /* #else */ | ||
66 | static int mh_mode=CRYPTO_MEM_CHECK_OFF; | 73 | static 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 | |||
67 | static unsigned long order=0; | 85 | static unsigned long order=0; |
68 | 86 | ||
69 | static LHASH *mh=NULL; | 87 | static LHASH *mh=NULL; |
@@ -72,25 +90,41 @@ typedef struct mem_st | |||
72 | { | 90 | { |
73 | char *addr; | 91 | char *addr; |
74 | int num; | 92 | int num; |
75 | char *file; | 93 | const char *file; |
76 | int line; | 94 | int line; |
95 | #ifdef CRYPTO_MDEBUG_THREAD | ||
96 | unsigned long thread; | ||
97 | #endif | ||
77 | unsigned long order; | 98 | unsigned long order; |
99 | #ifdef CRYPTO_MDEBUG_TIME | ||
100 | time_t time; | ||
101 | #endif | ||
78 | } MEM; | 102 | } MEM; |
79 | 103 | ||
80 | int CRYPTO_mem_ctrl(mode) | 104 | int CRYPTO_mem_ctrl(int mode) |
81 | int mode; | ||
82 | { | 105 | { |
83 | int ret=mh_mode; | 106 | int ret=mh_mode; |
84 | 107 | ||
85 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 108 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); |
86 | switch (mode) | 109 | switch (mode) |
87 | { | 110 | { |
88 | case CRYPTO_MEM_CHECK_ON: | 111 | /* for applications: */ |
89 | mh_mode|=CRYPTO_MEM_CHECK_ON; | 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; | ||
90 | break; | 117 | break; |
91 | case CRYPTO_MEM_CHECK_OFF: | 118 | |
92 | mh_mode&= ~CRYPTO_MEM_CHECK_ON; | 119 | /* switch off temporarily (for library-internal use): */ |
120 | case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ | ||
121 | mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE; | ||
93 | break; | 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 | |||
94 | default: | 128 | default: |
95 | break; | 129 | break; |
96 | } | 130 | } |
@@ -98,14 +132,12 @@ int mode; | |||
98 | return(ret); | 132 | return(ret); |
99 | } | 133 | } |
100 | 134 | ||
101 | static int mem_cmp(a,b) | 135 | static int mem_cmp(MEM *a, MEM *b) |
102 | MEM *a,*b; | ||
103 | { | 136 | { |
104 | return(a->addr - b->addr); | 137 | return(a->addr - b->addr); |
105 | } | 138 | } |
106 | 139 | ||
107 | static unsigned long mem_hash(a) | 140 | static unsigned long mem_hash(MEM *a) |
108 | MEM *a; | ||
109 | { | 141 | { |
110 | unsigned long ret; | 142 | unsigned long ret; |
111 | 143 | ||
@@ -115,54 +147,69 @@ MEM *a; | |||
115 | return(ret); | 147 | return(ret); |
116 | } | 148 | } |
117 | 149 | ||
150 | static char *(*malloc_locked_func)()=(char *(*)())malloc; | ||
151 | static void (*free_locked_func)()=(void (*)())free; | ||
118 | static char *(*malloc_func)()= (char *(*)())malloc; | 152 | static char *(*malloc_func)()= (char *(*)())malloc; |
119 | static char *(*realloc_func)()= (char *(*)())realloc; | 153 | static char *(*realloc_func)()= (char *(*)())realloc; |
120 | static void (*free_func)()= (void (*)())free; | 154 | static void (*free_func)()= (void (*)())free; |
121 | 155 | ||
122 | void CRYPTO_set_mem_functions(m,r,f) | 156 | void CRYPTO_set_mem_functions(char *(*m)(), char *(*r)(), void (*f)()) |
123 | char *(*m)(); | ||
124 | char *(*r)(); | ||
125 | void (*f)(); | ||
126 | { | 157 | { |
127 | if ((m == NULL) || (r == NULL) || (f == NULL)) return; | 158 | if ((m == NULL) || (r == NULL) || (f == NULL)) return; |
128 | malloc_func=m; | 159 | malloc_func=m; |
129 | realloc_func=r; | 160 | realloc_func=r; |
130 | free_func=f; | 161 | free_func=f; |
162 | malloc_locked_func=m; | ||
163 | free_locked_func=f; | ||
131 | } | 164 | } |
132 | 165 | ||
133 | void CRYPTO_get_mem_functions(m,r,f) | 166 | void CRYPTO_set_locked_mem_functions(char *(*m)(), void (*f)()) |
134 | char *(**m)(); | 167 | { |
135 | char *(**r)(); | 168 | if ((m == NULL) || (f == NULL)) return; |
136 | void (**f)(); | 169 | malloc_locked_func=m; |
170 | free_locked_func=f; | ||
171 | } | ||
172 | |||
173 | void CRYPTO_get_mem_functions(char *(**m)(), char *(**r)(), void (**f)()) | ||
137 | { | 174 | { |
138 | if (m != NULL) *m=malloc_func; | 175 | if (m != NULL) *m=malloc_func; |
139 | if (r != NULL) *r=realloc_func; | 176 | if (r != NULL) *r=realloc_func; |
140 | if (f != NULL) *f=free_func; | 177 | if (f != NULL) *f=free_func; |
141 | } | 178 | } |
142 | 179 | ||
143 | char *CRYPTO_malloc(num) | 180 | void CRYPTO_get_locked_mem_functions(char *(**m)(), void (**f)()) |
144 | int num; | 181 | { |
182 | if (m != NULL) *m=malloc_locked_func; | ||
183 | if (f != NULL) *f=free_locked_func; | ||
184 | } | ||
185 | |||
186 | void *CRYPTO_malloc_locked(int num) | ||
187 | { | ||
188 | return(malloc_locked_func(num)); | ||
189 | } | ||
190 | |||
191 | void CRYPTO_free_locked(void *str) | ||
192 | { | ||
193 | free_locked_func(str); | ||
194 | } | ||
195 | |||
196 | void *CRYPTO_malloc(int num) | ||
145 | { | 197 | { |
146 | return(malloc_func(num)); | 198 | return(malloc_func(num)); |
147 | } | 199 | } |
148 | 200 | ||
149 | char *CRYPTO_realloc(str,num) | 201 | void *CRYPTO_realloc(void *str, int num) |
150 | char *str; | ||
151 | int num; | ||
152 | { | 202 | { |
153 | return(realloc_func(str,num)); | 203 | return(realloc_func(str,num)); |
154 | } | 204 | } |
155 | 205 | ||
156 | void CRYPTO_free(str) | 206 | void CRYPTO_free(void *str) |
157 | char *str; | ||
158 | { | 207 | { |
159 | free_func(str); | 208 | free_func(str); |
160 | } | 209 | } |
161 | 210 | ||
162 | char *CRYPTO_dbg_malloc(num,file,line) | 211 | static unsigned long break_order_num=0; |
163 | int num; | 212 | void *CRYPTO_dbg_malloc(int num, const char *file, int line) |
164 | char *file; | ||
165 | int line; | ||
166 | { | 213 | { |
167 | char *ret; | 214 | char *ret; |
168 | MEM *m,*mm; | 215 | MEM *m,*mm; |
@@ -170,11 +217,13 @@ int line; | |||
170 | if ((ret=malloc_func(num)) == NULL) | 217 | if ((ret=malloc_func(num)) == NULL) |
171 | return(NULL); | 218 | return(NULL); |
172 | 219 | ||
173 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 220 | if (mh_mode & CRYPTO_MEM_CHECK_ENABLE) |
174 | { | 221 | { |
175 | if ((m=(MEM *)malloc(sizeof(MEM))) == NULL) | 222 | MemCheck_off(); |
223 | if ((m=(MEM *)Malloc(sizeof(MEM))) == NULL) | ||
176 | { | 224 | { |
177 | free(ret); | 225 | Free(ret); |
226 | MemCheck_on(); | ||
178 | return(NULL); | 227 | return(NULL); |
179 | } | 228 | } |
180 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 229 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); |
@@ -182,9 +231,10 @@ int line; | |||
182 | { | 231 | { |
183 | if ((mh=lh_new(mem_hash,mem_cmp)) == NULL) | 232 | if ((mh=lh_new(mem_hash,mem_cmp)) == NULL) |
184 | { | 233 | { |
185 | free(ret); | 234 | Free(ret); |
186 | free(m); | 235 | Free(m); |
187 | return(NULL); | 236 | ret=NULL; |
237 | goto err; | ||
188 | } | 238 | } |
189 | } | 239 | } |
190 | 240 | ||
@@ -192,39 +242,49 @@ int line; | |||
192 | m->file=file; | 242 | m->file=file; |
193 | m->line=line; | 243 | m->line=line; |
194 | m->num=num; | 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 | } | ||
195 | m->order=order++; | 253 | m->order=order++; |
254 | #ifdef CRYPTO_MDEBUG_TIME | ||
255 | m->time=time(NULL); | ||
256 | #endif | ||
196 | if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) | 257 | if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) |
197 | { | 258 | { |
198 | /* Not good, but don't sweat it */ | 259 | /* Not good, but don't sweat it */ |
199 | free(mm); | 260 | Free(mm); |
200 | } | 261 | } |
262 | err: | ||
201 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | 263 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); |
264 | MemCheck_on(); | ||
202 | } | 265 | } |
203 | return(ret); | 266 | return(ret); |
204 | } | 267 | } |
205 | 268 | ||
206 | void CRYPTO_dbg_free(addr) | 269 | void CRYPTO_dbg_free(void *addr) |
207 | char *addr; | ||
208 | { | 270 | { |
209 | MEM m,*mp; | 271 | MEM m,*mp; |
210 | 272 | ||
211 | if ((mh_mode & CRYPTO_MEM_CHECK_ON) && (mh != NULL)) | 273 | if ((mh_mode & CRYPTO_MEM_CHECK_ENABLE) && (mh != NULL)) |
212 | { | 274 | { |
275 | MemCheck_off(); | ||
213 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 276 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); |
214 | m.addr=addr; | 277 | m.addr=addr; |
215 | mp=(MEM *)lh_delete(mh,(char *)&m); | 278 | mp=(MEM *)lh_delete(mh,(char *)&m); |
216 | if (mp != NULL) | 279 | if (mp != NULL) |
217 | free(mp); | 280 | Free(mp); |
218 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | 281 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); |
282 | MemCheck_on(); | ||
219 | } | 283 | } |
220 | free_func(addr); | 284 | free_func(addr); |
221 | } | 285 | } |
222 | 286 | ||
223 | char *CRYPTO_dbg_realloc(addr,num,file,line) | 287 | void *CRYPTO_dbg_realloc(void *addr, int num, const char *file, int line) |
224 | char *addr; | ||
225 | int num; | ||
226 | char *file; | ||
227 | int line; | ||
228 | { | 288 | { |
229 | char *ret; | 289 | char *ret; |
230 | MEM m,*mp; | 290 | MEM m,*mp; |
@@ -232,8 +292,9 @@ int line; | |||
232 | ret=realloc_func(addr,num); | 292 | ret=realloc_func(addr,num); |
233 | if (ret == addr) return(ret); | 293 | if (ret == addr) return(ret); |
234 | 294 | ||
235 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 295 | if (mh_mode & CRYPTO_MEM_CHECK_ENABLE) |
236 | { | 296 | { |
297 | MemCheck_off(); | ||
237 | if (ret == NULL) return(NULL); | 298 | if (ret == NULL) return(NULL); |
238 | m.addr=addr; | 299 | m.addr=addr; |
239 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 300 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); |
@@ -244,24 +305,19 @@ int line; | |||
244 | lh_insert(mh,(char *)mp); | 305 | lh_insert(mh,(char *)mp); |
245 | } | 306 | } |
246 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | 307 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); |
308 | MemCheck_on(); | ||
247 | } | 309 | } |
248 | return(ret); | 310 | return(ret); |
249 | } | 311 | } |
250 | 312 | ||
251 | char *CRYPTO_remalloc(a,n) | 313 | void *CRYPTO_remalloc(void *a, int n) |
252 | char *a; | ||
253 | int n; | ||
254 | { | 314 | { |
255 | if (a != NULL) Free(a); | 315 | if (a != NULL) Free(a); |
256 | a=(char *)Malloc(n); | 316 | a=(char *)Malloc(n); |
257 | return(a); | 317 | return(a); |
258 | } | 318 | } |
259 | 319 | ||
260 | char *CRYPTO_dbg_remalloc(a,n,file,line) | 320 | void *CRYPTO_dbg_remalloc(void *a, int n, const char *file, int line) |
261 | char *a; | ||
262 | int n; | ||
263 | char *file; | ||
264 | int line; | ||
265 | { | 321 | { |
266 | if (a != NULL) CRYPTO_dbg_free(a); | 322 | if (a != NULL) CRYPTO_dbg_free(a); |
267 | a=(char *)CRYPTO_dbg_malloc(n,file,line); | 323 | a=(char *)CRYPTO_dbg_malloc(n,file,line); |
@@ -276,21 +332,44 @@ typedef struct mem_leak_st | |||
276 | long bytes; | 332 | long bytes; |
277 | } MEM_LEAK; | 333 | } MEM_LEAK; |
278 | 334 | ||
279 | static void print_leak(m,l) | 335 | static void print_leak(MEM *m, MEM_LEAK *l) |
280 | MEM *m; | ||
281 | MEM_LEAK *l; | ||
282 | { | 336 | { |
283 | char buf[128]; | 337 | char buf[128]; |
338 | #ifdef CRYPTO_MDEBUG_TIME | ||
339 | struct tm *lcl; | ||
340 | #endif | ||
341 | |||
342 | if(m->addr == (char *)l->bio) | ||
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); | ||
284 | 366 | ||
285 | sprintf(buf,"%5ld file=%s, line=%d, number=%d, address=%08lX\n", | ||
286 | m->order,m->file,m->line,m->num,(long)m->addr); | ||
287 | BIO_puts(l->bio,buf); | 367 | BIO_puts(l->bio,buf); |
288 | l->chunks++; | 368 | l->chunks++; |
289 | l->bytes+=m->num; | 369 | l->bytes+=m->num; |
290 | } | 370 | } |
291 | 371 | ||
292 | void CRYPTO_mem_leaks(b) | 372 | void CRYPTO_mem_leaks(BIO *b) |
293 | BIO *b; | ||
294 | { | 373 | { |
295 | MEM_LEAK ml; | 374 | MEM_LEAK ml; |
296 | char buf[80]; | 375 | char buf[80]; |
@@ -308,25 +387,23 @@ BIO *b; | |||
308 | ml.bytes,ml.chunks); | 387 | ml.bytes,ml.chunks); |
309 | BIO_puts(b,buf); | 388 | BIO_puts(b,buf); |
310 | } | 389 | } |
311 | /* | 390 | |
391 | #if 0 | ||
312 | lh_stats_bio(mh,b); | 392 | lh_stats_bio(mh,b); |
313 | lh_node_stats_bio(mh,b); | 393 | lh_node_stats_bio(mh,b); |
314 | lh_node_usage_stats_bio(mh,b); | 394 | lh_node_usage_stats_bio(mh,b); |
315 | */ | 395 | #endif |
316 | } | 396 | } |
317 | 397 | ||
318 | static void (*mem_cb)()=NULL; | 398 | static void (*mem_cb)()=NULL; |
319 | 399 | ||
320 | static void cb_leak(m,cb) | 400 | static void cb_leak(MEM *m, char *cb) |
321 | MEM *m; | ||
322 | char *cb; | ||
323 | { | 401 | { |
324 | void (*mem_callback)()=(void (*)())cb; | 402 | void (*mem_callback)()=(void (*)())cb; |
325 | mem_callback(m->order,m->file,m->line,m->num,m->addr); | 403 | mem_callback(m->order,m->file,m->line,m->num,m->addr); |
326 | } | 404 | } |
327 | 405 | ||
328 | void CRYPTO_mem_leaks_cb(cb) | 406 | void CRYPTO_mem_leaks_cb(void (*cb)()) |
329 | void (*cb)(); | ||
330 | { | 407 | { |
331 | if (mh == NULL) return; | 408 | if (mh == NULL) return; |
332 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 409 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); |
@@ -337,8 +414,7 @@ void (*cb)(); | |||
337 | } | 414 | } |
338 | 415 | ||
339 | #ifndef NO_FP_API | 416 | #ifndef NO_FP_API |
340 | void CRYPTO_mem_leaks_fp(fp) | 417 | void CRYPTO_mem_leaks_fp(FILE *fp) |
341 | FILE *fp; | ||
342 | { | 418 | { |
343 | BIO *b; | 419 | BIO *b; |
344 | 420 | ||