summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/mem.c
diff options
context:
space:
mode:
authormarkus <>2002-09-05 12:51:52 +0000
committermarkus <>2002-09-05 12:51:52 +0000
commit5514995a9d5ed91db089875adb509c7781357c0e (patch)
tree2484410a46ba6c05ef94c253da36fbceef990b64 /src/lib/libcrypto/mem.c
parentfd9566423b542798f5c8b06e68101a9ea5bb9885 (diff)
downloadopenbsd-5514995a9d5ed91db089875adb509c7781357c0e.tar.gz
openbsd-5514995a9d5ed91db089875adb509c7781357c0e.tar.bz2
openbsd-5514995a9d5ed91db089875adb509c7781357c0e.zip
import openssl-0.9.7-beta1
Diffstat (limited to 'src/lib/libcrypto/mem.c')
-rw-r--r--src/lib/libcrypto/mem.c454
1 files changed, 225 insertions, 229 deletions
diff --git a/src/lib/libcrypto/mem.c b/src/lib/libcrypto/mem.c
index 72e501ad0f..effec714e8 100644
--- a/src/lib/libcrypto/mem.c
+++ b/src/lib/libcrypto/mem.c
@@ -58,296 +58,292 @@
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"
63#include "lhash.h"
64#include "cryptlib.h" 62#include "cryptlib.h"
65 63
66static int mh_mode=CRYPTO_MEM_CHECK_OFF;
67static unsigned long order=0;
68 64
69static LHASH *mh=NULL; 65static int allow_customize = 1; /* we provide flexible functions for */
66static int allow_customize_debug = 1;/* exchanging memory-related functions at
67 * run-time, but this must be done
68 * before any blocks are actually
69 * allocated; or we'll run into huge
70 * problems when malloc/free pairs
71 * don't match etc. */
72
73
74
75/* the following pointers may be changed as long as 'allow_customize' is set */
76
77static void *(*malloc_func)(size_t) = malloc;
78static void *default_malloc_ex(size_t num, const char *file, int line)
79 { return malloc_func(num); }
80static void *(*malloc_ex_func)(size_t, const char *file, int line)
81 = default_malloc_ex;
82
83static void *(*realloc_func)(void *, size_t)= realloc;
84static void *default_realloc_ex(void *str, size_t num,
85 const char *file, int line)
86 { return realloc_func(str,num); }
87static void *(*realloc_ex_func)(void *, size_t, const char *file, int line)
88 = default_realloc_ex;
89
90static void (*free_func)(void *) = free;
91
92static void *(*malloc_locked_func)(size_t) = malloc;
93static void *default_malloc_locked_ex(size_t num, const char *file, int line)
94 { return malloc_locked_func(num); }
95static void *(*malloc_locked_ex_func)(size_t, const char *file, int line)
96 = default_malloc_locked_ex;
97
98static void (*free_locked_func)(void *) = free;
99
100
101
102/* may be changed as long as 'allow_customize_debug' is set */
103/* XXX use correct function pointer types */
104#ifdef CRYPTO_MDEBUG
105/* use default functions from mem_dbg.c */
106static void (*malloc_debug_func)(void *,int,const char *,int,int)
107 = CRYPTO_dbg_malloc;
108static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
109 = CRYPTO_dbg_realloc;
110static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free;
111static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;
112static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;
113#else
114/* applications can use CRYPTO_malloc_debug_init() to select above case
115 * at run-time */
116static void (*malloc_debug_func)(void *,int,const char *,int,int) = NULL;
117static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
118 = NULL;
119static void (*free_debug_func)(void *,int) = NULL;
120static void (*set_debug_options_func)(long) = NULL;
121static long (*get_debug_options_func)(void) = NULL;
122#endif
70 123
71typedef struct mem_st
72 {
73 char *addr;
74 int num;
75 char *file;
76 int line;
77 unsigned long order;
78 } MEM;
79
80int CRYPTO_mem_ctrl(mode)
81int mode;
82 {
83 int ret=mh_mode;
84 124
85 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); 125int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
86 switch (mode) 126 void (*f)(void *))
87 { 127 {
88 case CRYPTO_MEM_CHECK_ON: 128 if (!allow_customize)
89 mh_mode|=CRYPTO_MEM_CHECK_ON; 129 return 0;
90 break; 130 if ((m == 0) || (r == 0) || (f == 0))
91 case CRYPTO_MEM_CHECK_OFF: 131 return 0;
92 mh_mode&= ~CRYPTO_MEM_CHECK_ON; 132 malloc_func=m; malloc_ex_func=default_malloc_ex;
93 break; 133 realloc_func=r; realloc_ex_func=default_realloc_ex;
94 default: 134 free_func=f;
95 break; 135 malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
96 } 136 free_locked_func=f;
97 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); 137 return 1;
98 return(ret);
99 } 138 }
100 139
101static int mem_cmp(a,b) 140int CRYPTO_set_mem_ex_functions(
102MEM *a,*b; 141 void *(*m)(size_t,const char *,int),
142 void *(*r)(void *, size_t,const char *,int),
143 void (*f)(void *))
103 { 144 {
104 return(a->addr - b->addr); 145 if (!allow_customize)
146 return 0;
147 if ((m == 0) || (r == 0) || (f == 0))
148 return 0;
149 malloc_func=0; malloc_ex_func=m;
150 realloc_func=0; realloc_ex_func=r;
151 free_func=f;
152 malloc_locked_func=0; malloc_locked_ex_func=m;
153 free_locked_func=f;
154 return 1;
105 } 155 }
106 156
107static unsigned long mem_hash(a) 157int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *))
108MEM *a;
109 { 158 {
110 unsigned long ret; 159 if (!allow_customize)
160 return 0;
161 if ((m == NULL) || (f == NULL))
162 return 0;
163 malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
164 free_locked_func=f;
165 return 1;
166 }
111 167
112 ret=(unsigned long)a->addr; 168int CRYPTO_set_locked_mem_ex_functions(
169 void *(*m)(size_t,const char *,int),
170 void (*f)(void *))
171 {
172 if (!allow_customize)
173 return 0;
174 if ((m == NULL) || (f == NULL))
175 return 0;
176 malloc_locked_func=0; malloc_locked_ex_func=m;
177 free_func=f;
178 return 1;
179 }
113 180
114 ret=ret*17851+(ret>>14)*7+(ret>>4)*251; 181int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
115 return(ret); 182 void (*r)(void *,void *,int,const char *,int,int),
183 void (*f)(void *,int),
184 void (*so)(long),
185 long (*go)(void))
186 {
187 if (!allow_customize_debug)
188 return 0;
189 malloc_debug_func=m;
190 realloc_debug_func=r;
191 free_debug_func=f;
192 set_debug_options_func=so;
193 get_debug_options_func=go;
194 return 1;
116 } 195 }
117 196
118static char *(*malloc_func)()= (char *(*)())malloc;
119static char *(*realloc_func)()= (char *(*)())realloc;
120static void (*free_func)()= (void (*)())free;
121 197
122void CRYPTO_set_mem_functions(m,r,f) 198void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
123char *(*m)(); 199 void (**f)(void *))
124char *(*r)();
125void (*f)();
126 { 200 {
127 if ((m == NULL) || (r == NULL) || (f == NULL)) return; 201 if (m != NULL) *m = (malloc_ex_func == default_malloc_ex) ?
128 malloc_func=m; 202 malloc_func : 0;
129 realloc_func=r; 203 if (r != NULL) *r = (realloc_ex_func == default_realloc_ex) ?
130 free_func=f; 204 realloc_func : 0;
205 if (f != NULL) *f=free_func;
131 } 206 }
132 207
133void CRYPTO_get_mem_functions(m,r,f) 208void CRYPTO_get_mem_ex_functions(
134char *(**m)(); 209 void *(**m)(size_t,const char *,int),
135char *(**r)(); 210 void *(**r)(void *, size_t,const char *,int),
136void (**f)(); 211 void (**f)(void *))
137 { 212 {
138 if (m != NULL) *m=malloc_func; 213 if (m != NULL) *m = (malloc_ex_func != default_malloc_ex) ?
139 if (r != NULL) *r=realloc_func; 214 malloc_ex_func : 0;
215 if (r != NULL) *r = (realloc_ex_func != default_realloc_ex) ?
216 realloc_ex_func : 0;
140 if (f != NULL) *f=free_func; 217 if (f != NULL) *f=free_func;
141 } 218 }
142 219
143char *CRYPTO_malloc(num) 220void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *))
144int num;
145 { 221 {
146 return(malloc_func(num)); 222 if (m != NULL) *m = (malloc_locked_ex_func == default_malloc_locked_ex) ?
223 malloc_locked_func : 0;
224 if (f != NULL) *f=free_locked_func;
147 } 225 }
148 226
149char *CRYPTO_realloc(str,num) 227void CRYPTO_get_locked_mem_ex_functions(
150char *str; 228 void *(**m)(size_t,const char *,int),
151int num; 229 void (**f)(void *))
152 { 230 {
153 return(realloc_func(str,num)); 231 if (m != NULL) *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
232 malloc_locked_ex_func : 0;
233 if (f != NULL) *f=free_locked_func;
154 } 234 }
155 235
156void CRYPTO_free(str) 236void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
157char *str; 237 void (**r)(void *,void *,int,const char *,int,int),
238 void (**f)(void *,int),
239 void (**so)(long),
240 long (**go)(void))
158 { 241 {
159 free_func(str); 242 if (m != NULL) *m=malloc_debug_func;
243 if (r != NULL) *r=realloc_debug_func;
244 if (f != NULL) *f=free_debug_func;
245 if (so != NULL) *so=set_debug_options_func;
246 if (go != NULL) *go=get_debug_options_func;
160 } 247 }
161 248
162char *CRYPTO_dbg_malloc(num,file,line)
163int num;
164char *file;
165int line;
166 {
167 char *ret;
168 MEM *m,*mm;
169 249
170 if ((ret=malloc_func(num)) == NULL) 250void *CRYPTO_malloc_locked(int num, const char *file, int line)
171 return(NULL); 251 {
252 void *ret = NULL;
172 253
173 if (mh_mode & CRYPTO_MEM_CHECK_ON) 254 allow_customize = 0;
255 if (malloc_debug_func != NULL)
174 { 256 {
175 if ((m=(MEM *)malloc(sizeof(MEM))) == NULL) 257 allow_customize_debug = 0;
176 { 258 malloc_debug_func(NULL, num, file, line, 0);
177 free(ret);
178 return(NULL);
179 }
180 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
181 if (mh == NULL)
182 {
183 if ((mh=lh_new(mem_hash,mem_cmp)) == NULL)
184 {
185 free(ret);
186 free(m);
187 return(NULL);
188 }
189 }
190
191 m->addr=ret;
192 m->file=file;
193 m->line=line;
194 m->num=num;
195 m->order=order++;
196 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
197 {
198 /* Not good, but don't sweat it */
199 free(mm);
200 }
201 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
202 } 259 }
203 return(ret); 260 ret = malloc_locked_ex_func(num,file,line);
261#ifdef LEVITTE_DEBUG_MEM
262 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
263#endif
264 if (malloc_debug_func != NULL)
265 malloc_debug_func(ret, num, file, line, 1);
266
267 return ret;
204 } 268 }
205 269
206void CRYPTO_dbg_free(addr) 270void CRYPTO_free_locked(void *str)
207char *addr;
208 { 271 {
209 MEM m,*mp; 272 if (free_debug_func != NULL)
210 273 free_debug_func(str, 0);
211 if ((mh_mode & CRYPTO_MEM_CHECK_ON) && (mh != NULL)) 274#ifdef LEVITTE_DEBUG_MEM
212 { 275 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
213 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); 276#endif
214 m.addr=addr; 277 free_locked_func(str);
215 mp=(MEM *)lh_delete(mh,(char *)&m); 278 if (free_debug_func != NULL)
216 if (mp != NULL) 279 free_debug_func(NULL, 1);
217 free(mp);
218 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
219 }
220 free_func(addr);
221 } 280 }
222 281
223char *CRYPTO_dbg_realloc(addr,num,file,line) 282void *CRYPTO_malloc(int num, const char *file, int line)
224char *addr;
225int num;
226char *file;
227int line;
228 { 283 {
229 char *ret; 284 void *ret = NULL;
230 MEM m,*mp;
231
232 ret=realloc_func(addr,num);
233 if (ret == addr) return(ret);
234 285
235 if (mh_mode & CRYPTO_MEM_CHECK_ON) 286 allow_customize = 0;
287 if (malloc_debug_func != NULL)
236 { 288 {
237 if (ret == NULL) return(NULL); 289 allow_customize_debug = 0;
238 m.addr=addr; 290 malloc_debug_func(NULL, num, file, line, 0);
239 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
240 mp=(MEM *)lh_delete(mh,(char *)&m);
241 if (mp != NULL)
242 {
243 mp->addr=ret;
244 lh_insert(mh,(char *)mp);
245 }
246 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
247 } 291 }
248 return(ret); 292 ret = malloc_ex_func(num,file,line);
249 } 293#ifdef LEVITTE_DEBUG_MEM
294 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
295#endif
296 if (malloc_debug_func != NULL)
297 malloc_debug_func(ret, num, file, line, 1);
250 298
251char *CRYPTO_remalloc(a,n) 299 return ret;
252char *a;
253int n;
254 {
255 if (a != NULL) Free(a);
256 a=(char *)Malloc(n);
257 return(a);
258 } 300 }
259 301
260char *CRYPTO_dbg_remalloc(a,n,file,line) 302void *CRYPTO_realloc(void *str, int num, const char *file, int line)
261char *a;
262int n;
263char *file;
264int line;
265 { 303 {
266 if (a != NULL) CRYPTO_dbg_free(a); 304 void *ret = NULL;
267 a=(char *)CRYPTO_dbg_malloc(n,file,line);
268 return(a);
269 }
270 305
306 if (realloc_debug_func != NULL)
307 realloc_debug_func(str, NULL, num, file, line, 0);
308 ret = realloc_ex_func(str,num,file,line);
309#ifdef LEVITTE_DEBUG_MEM
310 fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, ret, num);
311#endif
312 if (realloc_debug_func != NULL)
313 realloc_debug_func(str, ret, num, file, line, 1);
271 314
272typedef struct mem_leak_st 315 return ret;
273 {
274 BIO *bio;
275 int chunks;
276 long bytes;
277 } MEM_LEAK;
278
279static void print_leak(m,l)
280MEM *m;
281MEM_LEAK *l;
282 {
283 char buf[128];
284
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);
288 l->chunks++;
289 l->bytes+=m->num;
290 } 316 }
291 317
292void CRYPTO_mem_leaks(b) 318void CRYPTO_free(void *str)
293BIO *b;
294 { 319 {
295 MEM_LEAK ml; 320 if (free_debug_func != NULL)
296 char buf[80]; 321 free_debug_func(str, 0);
297 322#ifdef LEVITTE_DEBUG_MEM
298 if (mh == NULL) return; 323 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
299 ml.bio=b; 324#endif
300 ml.bytes=0; 325 free_func(str);
301 ml.chunks=0; 326 if (free_debug_func != NULL)
302 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); 327 free_debug_func(NULL, 1);
303 lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml);
304 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
305 if (ml.chunks != 0)
306 {
307 sprintf(buf,"%ld bytes leaked in %d chunks\n",
308 ml.bytes,ml.chunks);
309 BIO_puts(b,buf);
310 }
311 /*
312 lh_stats_bio(mh,b);
313 lh_node_stats_bio(mh,b);
314 lh_node_usage_stats_bio(mh,b);
315 */
316 } 328 }
317 329
318static void (*mem_cb)()=NULL; 330void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
319
320static void cb_leak(m,cb)
321MEM *m;
322char *cb;
323 { 331 {
324 void (*mem_callback)()=(void (*)())cb; 332 if (a != NULL) OPENSSL_free(a);
325 mem_callback(m->order,m->file,m->line,m->num,m->addr); 333 a=(char *)OPENSSL_malloc(num);
334 return(a);
326 } 335 }
327 336
328void CRYPTO_mem_leaks_cb(cb) 337
329void (*cb)(); 338void CRYPTO_set_mem_debug_options(long bits)
330 { 339 {
331 if (mh == NULL) return; 340 if (set_debug_options_func != NULL)
332 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); 341 set_debug_options_func(bits);
333 mem_cb=cb;
334 lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
335 mem_cb=NULL;
336 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
337 } 342 }
338 343
339#ifndef NO_FP_API 344long CRYPTO_get_mem_debug_options(void)
340void CRYPTO_mem_leaks_fp(fp)
341FILE *fp;
342 { 345 {
343 BIO *b; 346 if (get_debug_options_func != NULL)
344 347 return get_debug_options_func();
345 if (mh == NULL) return; 348 return 0;
346 if ((b=BIO_new(BIO_s_file())) == NULL)
347 return;
348 BIO_set_fp(b,fp,BIO_NOCLOSE);
349 CRYPTO_mem_leaks(b);
350 BIO_free(b);
351 } 349 }
352#endif
353