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 '')
| -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 | ||
