Diffstat (limited to 'pwmanager/libcrypt/crypt/secmem.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/crypt/secmem.c | 653 |
1 files changed, 653 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/crypt/secmem.c b/pwmanager/libcrypt/crypt/secmem.c new file mode 100644 index 0000000..163bf20 --- a/dev/null +++ b/pwmanager/libcrypt/crypt/secmem.c | |||
@@ -0,0 +1,653 @@ | |||
1 | /* secmem.c -memory allocation from a secure heap | ||
2 | * Copyright (C) 1998, 1999, 2000, 2001, 2002, | ||
3 | * 2003 Free Software Foundation, Inc. | ||
4 | * | ||
5 | * This file is part of Libgcrypt. | ||
6 | * | ||
7 | * Libgcrypt is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser general Public License as | ||
9 | * published by the Free Software Foundation; either version 2.1 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | * | ||
12 | * Libgcrypt is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
20 | */ | ||
21 | |||
22 | #include <config.h> | ||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <errno.h> | ||
27 | #include <stdarg.h> | ||
28 | #include <unistd.h> | ||
29 | #include <stddef.h> | ||
30 | |||
31 | #if defined(HAVE_MLOCK) || defined(HAVE_MMAP) | ||
32 | #include <sys/mman.h> | ||
33 | #include <sys/types.h> | ||
34 | #include <fcntl.h> | ||
35 | #ifdef USE_CAPABILITIES | ||
36 | #include <sys/capability.h> | ||
37 | #endif | ||
38 | #endif | ||
39 | |||
40 | #include "ath.h" | ||
41 | #include "g10lib.h" | ||
42 | #include "secmem.h" | ||
43 | |||
44 | #if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS) | ||
45 | #define MAP_ANONYMOUS MAP_ANON | ||
46 | #endif | ||
47 | |||
48 | #define DEFAULT_POOL_SIZE 16384 | ||
49 | #define DEFAULT_PAGE_SIZE 4096 | ||
50 | |||
51 | typedef struct memblock | ||
52 | { | ||
53 | unsigned size; /* Size of the memory available to the | ||
54 | user. */ | ||
55 | int flags; /* See below. */ | ||
56 | PROPERLY_ALIGNED_TYPE aligned; | ||
57 | } memblock_t; | ||
58 | |||
59 | /* This flag specifies that the memory block is in use. */ | ||
60 | #define MB_FLAG_ACTIVE 1 << 0 | ||
61 | |||
62 | /* The pool of secure memory. */ | ||
63 | static void *pool; | ||
64 | |||
65 | /* Size of POOL in bytes. */ | ||
66 | static size_t pool_size; | ||
67 | |||
68 | /* True, if the memory pool is ready for use. May be checked in an | ||
69 | atexit function. */ | ||
70 | static volatile int pool_okay; | ||
71 | |||
72 | /* True, if the memory pool is mmapped. */ | ||
73 | static volatile int pool_is_mmapped; | ||
74 | |||
75 | /* FIXME? */ | ||
76 | static int disable_secmem; | ||
77 | static int show_warning; | ||
78 | static int no_warning; | ||
79 | static int suspend_warning; | ||
80 | |||
81 | /* Stats. */ | ||
82 | static unsigned int cur_alloced, cur_blocks; | ||
83 | |||
84 | /* Lock protecting accesses to the memory pool. */ | ||
85 | static ath_mutex_t secmem_lock; | ||
86 | |||
87 | /* Convenient macros. */ | ||
88 | #define SECMEM_LOCK ath_mutex_lock (&secmem_lock) | ||
89 | #define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock) | ||
90 | |||
91 | /* The size of the memblock structure; this does not include the | ||
92 | memory that is available to the user. */ | ||
93 | #define BLOCK_HEAD_SIZE \ | ||
94 | offsetof (memblock_t, aligned) | ||
95 | |||
96 | /* Convert an address into the according memory block structure. */ | ||
97 | #define ADDR_TO_BLOCK(addr) \ | ||
98 | (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE) | ||
99 | |||
100 | /* Check wether MB is a valid block. */ | ||
101 | #define BLOCK_VALID(mb) \ | ||
102 | (((char *) mb - (char *) pool) < pool_size) | ||
103 | |||
104 | /* Update the stats. */ | ||
105 | static void | ||
106 | stats_update (size_t add, size_t sub) | ||
107 | { | ||
108 | if (add) | ||
109 | { | ||
110 | cur_alloced += add; | ||
111 | cur_blocks++; | ||
112 | } | ||
113 | if (sub) | ||
114 | { | ||
115 | cur_alloced -= sub; | ||
116 | cur_blocks--; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | /* Return the block following MB or NULL, if MB is the last block. */ | ||
121 | static memblock_t * | ||
122 | mb_get_next (memblock_t *mb) | ||
123 | { | ||
124 | memblock_t *mb_next; | ||
125 | |||
126 | mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size); | ||
127 | |||
128 | if (! BLOCK_VALID (mb_next)) | ||
129 | mb_next = NULL; | ||
130 | |||
131 | return mb_next; | ||
132 | } | ||
133 | |||
134 | /* Return the block preceeding MB or NULL, if MB is the first | ||
135 | block. */ | ||
136 | static memblock_t * | ||
137 | mb_get_prev (memblock_t *mb) | ||
138 | { | ||
139 | memblock_t *mb_prev, *mb_next; | ||
140 | |||
141 | if (mb == pool) | ||
142 | mb_prev = NULL; | ||
143 | else | ||
144 | { | ||
145 | mb_prev = (memblock_t *) pool; | ||
146 | while (1) | ||
147 | { | ||
148 | mb_next = mb_get_next (mb_prev); | ||
149 | if (mb_next == mb) | ||
150 | break; | ||
151 | else | ||
152 | mb_prev = mb_next; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | return mb_prev; | ||
157 | } | ||
158 | |||
159 | /* If the preceeding block of MB and/or the following block of MB | ||
160 | exist and are not active, merge them to form a bigger block. */ | ||
161 | static void | ||
162 | mb_merge (memblock_t *mb) | ||
163 | { | ||
164 | memblock_t *mb_prev, *mb_next; | ||
165 | |||
166 | mb_prev = mb_get_prev (mb); | ||
167 | mb_next = mb_get_next (mb); | ||
168 | |||
169 | if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE))) | ||
170 | { | ||
171 | mb_prev->size += BLOCK_HEAD_SIZE + mb->size; | ||
172 | mb = mb_prev; | ||
173 | } | ||
174 | if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE))) | ||
175 | mb->size += BLOCK_HEAD_SIZE + mb_next->size; | ||
176 | } | ||
177 | |||
178 | /* Return a new block, which can hold SIZE bytes. */ | ||
179 | static memblock_t * | ||
180 | mb_get_new (memblock_t *block, size_t size) | ||
181 | { | ||
182 | memblock_t *mb, *mb_split; | ||
183 | |||
184 | for (mb = block; BLOCK_VALID (mb); mb = mb_get_next (mb)) | ||
185 | if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size) | ||
186 | { | ||
187 | /* Found a free block. */ | ||
188 | mb->flags |= MB_FLAG_ACTIVE; | ||
189 | |||
190 | if (mb->size - size > BLOCK_HEAD_SIZE) | ||
191 | { | ||
192 | /* Split block. */ | ||
193 | |||
194 | mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size); | ||
195 | mb_split->size = mb->size - size - BLOCK_HEAD_SIZE; | ||
196 | mb_split->flags = 0; | ||
197 | |||
198 | mb->size = size; | ||
199 | |||
200 | mb_merge (mb_split); | ||
201 | |||
202 | } | ||
203 | |||
204 | break; | ||
205 | } | ||
206 | |||
207 | if (! BLOCK_VALID (mb)) | ||
208 | mb = NULL; | ||
209 | |||
210 | return mb; | ||
211 | } | ||
212 | |||
213 | /* Print a warning message. */ | ||
214 | static void | ||
215 | print_warn (void) | ||
216 | { | ||
217 | if (!no_warning) | ||
218 | log_info (_("Warning: using insecure memory!\n")); | ||
219 | } | ||
220 | |||
221 | /* Lock the memory pages into core and drop privileges. */ | ||
222 | static void | ||
223 | lock_pool (void *p, size_t n) | ||
224 | { | ||
225 | #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK) | ||
226 | int err; | ||
227 | |||
228 | cap_set_proc (cap_from_text ("cap_ipc_lock+ep")); | ||
229 | err = mlock (p, n); | ||
230 | if (err && errno) | ||
231 | err = errno; | ||
232 | cap_set_proc (cap_from_text ("cap_ipc_lock+p")); | ||
233 | |||
234 | if (err) | ||
235 | { | ||
236 | if (errno != EPERM | ||
237 | #ifdef EAGAIN/* OpenBSD returns this */ | ||
238 | && errno != EAGAIN | ||
239 | #endif | ||
240 | #ifdef ENOSYS/* Some SCOs return this (function not implemented) */ | ||
241 | && errno != ENOSYS | ||
242 | #endif | ||
243 | #ifdef ENOMEM /* Linux might return this. */ | ||
244 | && errno != ENOMEM | ||
245 | #endif | ||
246 | ) | ||
247 | log_error ("can't lock memory: %s\n", strerror (err)); | ||
248 | show_warning = 1; | ||
249 | } | ||
250 | |||
251 | #elif defined(HAVE_MLOCK) | ||
252 | uid_t uid; | ||
253 | int err; | ||
254 | |||
255 | uid = getuid (); | ||
256 | |||
257 | #ifdef HAVE_BROKEN_MLOCK | ||
258 | /* Under HP/UX mlock segfaults if called by non-root. Note, we have | ||
259 | noch checked whether mlock does really work under AIX where we | ||
260 | also detected a broken nlock. Note further, that using plock () | ||
261 | is not a good idea under AIX. */ | ||
262 | if (uid) | ||
263 | { | ||
264 | errno = EPERM; | ||
265 | err = errno; | ||
266 | } | ||
267 | else | ||
268 | { | ||
269 | err = mlock (p, n); | ||
270 | if (err && errno) | ||
271 | err = errno; | ||
272 | } | ||
273 | #else /* !HAVE_BROKEN_MLOCK */ | ||
274 | err = mlock (p, n); | ||
275 | if (err && errno) | ||
276 | err = errno; | ||
277 | #endif /* !HAVE_BROKEN_MLOCK */ | ||
278 | |||
279 | if (uid && ! geteuid ()) | ||
280 | { | ||
281 | /* check that we really dropped the privs. | ||
282 | * Note: setuid(0) should always fail */ | ||
283 | if (setuid (uid) || getuid () != geteuid () || !setuid (0)) | ||
284 | log_fatal ("failed to reset uid: %s\n", strerror (errno)); | ||
285 | } | ||
286 | |||
287 | if (err) | ||
288 | { | ||
289 | if (errno != EPERM | ||
290 | #ifdef EAGAIN/* OpenBSD returns this. */ | ||
291 | && errno != EAGAIN | ||
292 | #endif | ||
293 | #ifdef ENOSYS/* Some SCOs return this (function not implemented). */ | ||
294 | && errno != ENOSYS | ||
295 | #endif | ||
296 | #ifdef ENOMEM /* Linux might return this. */ | ||
297 | && errno != ENOMEM | ||
298 | #endif | ||
299 | ) | ||
300 | log_error ("can't lock memory: %s\n", strerror (err)); | ||
301 | show_warning = 1; | ||
302 | } | ||
303 | |||
304 | #elif defined ( __QNX__ ) | ||
305 | /* QNX does not page at all, so the whole secure memory stuff does | ||
306 | * not make much sense. However it is still of use because it | ||
307 | * wipes out the memory on a free(). | ||
308 | * Therefore it is sufficient to suppress the warning | ||
309 | */ | ||
310 | #elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__) | ||
311 | /* It does not make sense to print such a warning, given the fact that | ||
312 | * this whole Windows !@#$% and their user base are inherently insecure | ||
313 | */ | ||
314 | #elif defined (__riscos__) | ||
315 | /* no virtual memory on RISC OS, so no pages are swapped to disc, | ||
316 | * besides we don't have mmap, so we don't use it! ;-) | ||
317 | * But don't complain, as explained above. | ||
318 | */ | ||
319 | #else | ||
320 | log_info ("Please note that you don't have secure memory on this system\n"); | ||
321 | #endif | ||
322 | } | ||
323 | |||
324 | /* Initialize POOL. */ | ||
325 | static void | ||
326 | init_pool (size_t n) | ||
327 | { | ||
328 | size_t pgsize; | ||
329 | memblock_t *mb; | ||
330 | |||
331 | pool_size = n; | ||
332 | |||
333 | if (disable_secmem) | ||
334 | log_bug ("secure memory is disabled"); | ||
335 | |||
336 | #ifdef HAVE_GETPAGESIZE | ||
337 | pgsize = getpagesize (); | ||
338 | #else | ||
339 | pgsize = DEFAULT_PAGE_SIZE; | ||
340 | #endif | ||
341 | |||
342 | #if HAVE_MMAP | ||
343 | pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1); | ||
344 | #ifdef MAP_ANONYMOUS | ||
345 | pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, | ||
346 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||
347 | #else /* map /dev/zero instead */ | ||
348 | { | ||
349 | int fd; | ||
350 | |||
351 | fd = open ("/dev/zero", O_RDWR); | ||
352 | if (fd == -1) | ||
353 | { | ||
354 | log_error ("can't open /dev/zero: %s\n", strerror (errno)); | ||
355 | pool = (void *) -1; | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | ||
360 | } | ||
361 | } | ||
362 | #endif | ||
363 | if (pool == (void *) -1) | ||
364 | log_info ("can't mmap pool of %u bytes: %s - using malloc\n", | ||
365 | (unsigned) pool_size, strerror (errno)); | ||
366 | else | ||
367 | { | ||
368 | pool_is_mmapped = 1; | ||
369 | pool_okay = 1; | ||
370 | } | ||
371 | |||
372 | #endif | ||
373 | if (!pool_okay) | ||
374 | { | ||
375 | pool = malloc (pool_size); | ||
376 | if (!pool) | ||
377 | log_fatal ("can't allocate memory pool of %u bytes\n", | ||
378 | (unsigned) pool_size); | ||
379 | else | ||
380 | pool_okay = 1; | ||
381 | } | ||
382 | |||
383 | /* Initialize first memory block. */ | ||
384 | mb = (memblock_t *) pool; | ||
385 | mb->size = pool_size; | ||
386 | mb->flags = 0; | ||
387 | } | ||
388 | |||
389 | void | ||
390 | _gcry_secmem_set_flags (unsigned flags) | ||
391 | { | ||
392 | int was_susp; | ||
393 | |||
394 | SECMEM_LOCK; | ||
395 | |||
396 | was_susp = suspend_warning; | ||
397 | no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING; | ||
398 | suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING; | ||
399 | |||
400 | /* and now issue the warning if it is not longer suspended */ | ||
401 | if (was_susp && !suspend_warning && show_warning) | ||
402 | { | ||
403 | show_warning = 0; | ||
404 | print_warn (); | ||
405 | } | ||
406 | |||
407 | SECMEM_UNLOCK; | ||
408 | } | ||
409 | |||
410 | unsigned | ||
411 | _gcry_secmem_get_flags (void) | ||
412 | { | ||
413 | unsigned flags; | ||
414 | |||
415 | SECMEM_LOCK; | ||
416 | |||
417 | flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0; | ||
418 | flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0; | ||
419 | |||
420 | SECMEM_UNLOCK; | ||
421 | |||
422 | return flags; | ||
423 | } | ||
424 | |||
425 | /* Initialize the secure memory system. If running with the necessary | ||
426 | privileges, the secure memory pool will be locked into the core in | ||
427 | order to prevent page-outs of the data. Furthermore allocated | ||
428 | secure memory will be wiped out when released. */ | ||
429 | void | ||
430 | _gcry_secmem_init (size_t n) | ||
431 | { | ||
432 | SECMEM_LOCK; | ||
433 | |||
434 | if (!n) | ||
435 | { | ||
436 | #ifdef USE_CAPABILITIES | ||
437 | /* drop all capabilities */ | ||
438 | cap_set_proc (cap_from_text ("all-eip")); | ||
439 | |||
440 | #elif !defined(HAVE_DOSISH_SYSTEM) | ||
441 | uid_t uid; | ||
442 | |||
443 | disable_secmem = 1; | ||
444 | uid = getuid (); | ||
445 | if (uid != geteuid ()) | ||
446 | { | ||
447 | if (setuid (uid) || getuid () != geteuid () || !setuid (0)) | ||
448 | log_fatal ("failed to drop setuid\n"); | ||
449 | } | ||
450 | #endif | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | if (n < DEFAULT_POOL_SIZE) | ||
455 | n = DEFAULT_POOL_SIZE; | ||
456 | if (! pool_okay) | ||
457 | { | ||
458 | init_pool (n); | ||
459 | if (! geteuid ()) | ||
460 | lock_pool (pool, n); | ||
461 | else if (!no_warning) | ||
462 | log_info ("Secure memory is not locked into core\n"); | ||
463 | } | ||
464 | else | ||
465 | log_error ("Oops, secure memory pool already initialized\n"); | ||
466 | } | ||
467 | |||
468 | SECMEM_UNLOCK; | ||
469 | } | ||
470 | |||
471 | |||
472 | static void * | ||
473 | _gcry_secmem_malloc_internal (size_t size) | ||
474 | { | ||
475 | memblock_t *mb; | ||
476 | |||
477 | if (!pool_okay) | ||
478 | { | ||
479 | log_info (_ | ||
480 | ("operation is not possible without initialized secure memory\n")); | ||
481 | exit (2); | ||
482 | } | ||
483 | if (show_warning && !suspend_warning) | ||
484 | { | ||
485 | show_warning = 0; | ||
486 | print_warn (); | ||
487 | } | ||
488 | |||
489 | /* Blocks are always a multiple of 32. */ | ||
490 | size = ((size + 31) / 32) * 32; | ||
491 | |||
492 | mb = mb_get_new ((memblock_t *) pool, size); | ||
493 | if (mb) | ||
494 | stats_update (size, 0); | ||
495 | |||
496 | return mb ? &mb->aligned.c : NULL; | ||
497 | } | ||
498 | |||
499 | void * | ||
500 | _gcry_secmem_malloc (size_t size) | ||
501 | { | ||
502 | void *p; | ||
503 | |||
504 | SECMEM_LOCK; | ||
505 | p = _gcry_secmem_malloc_internal (size); | ||
506 | SECMEM_UNLOCK; | ||
507 | |||
508 | return p; | ||
509 | } | ||
510 | |||
511 | static void | ||
512 | _gcry_secmem_free_internal (void *a) | ||
513 | { | ||
514 | memblock_t *mb; | ||
515 | int size; | ||
516 | |||
517 | if (!a) | ||
518 | return; | ||
519 | |||
520 | mb = ADDR_TO_BLOCK (a); | ||
521 | size = mb->size; | ||
522 | |||
523 | /* This does not make much sense: probably this memory is held in the | ||
524 | * cache. We do it anyway: */ | ||
525 | #define MB_WIPE_OUT(byte) \ | ||
526 | memset ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); | ||
527 | |||
528 | MB_WIPE_OUT (0xff); | ||
529 | MB_WIPE_OUT (0xaa); | ||
530 | MB_WIPE_OUT (0x55); | ||
531 | MB_WIPE_OUT (0x00); | ||
532 | |||
533 | stats_update (0, size); | ||
534 | |||
535 | mb->flags &= ~MB_FLAG_ACTIVE; | ||
536 | |||
537 | /* Update stats. */ | ||
538 | |||
539 | mb_merge (mb); | ||
540 | } | ||
541 | |||
542 | /* Wipe out and release memory. */ | ||
543 | void | ||
544 | _gcry_secmem_free (void *a) | ||
545 | { | ||
546 | SECMEM_LOCK; | ||
547 | _gcry_secmem_free_internal (a); | ||
548 | SECMEM_UNLOCK; | ||
549 | } | ||
550 | |||
551 | /* Realloc memory. */ | ||
552 | void * | ||
553 | _gcry_secmem_realloc (void *p, size_t newsize) | ||
554 | { | ||
555 | memblock_t *mb; | ||
556 | size_t size; | ||
557 | void *a; | ||
558 | |||
559 | SECMEM_LOCK; | ||
560 | |||
561 | mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c)); | ||
562 | size = mb->size; | ||
563 | if (newsize < size) | ||
564 | { | ||
565 | /* It is easier to not shrink the memory. */ | ||
566 | a = p; | ||
567 | } | ||
568 | else | ||
569 | { | ||
570 | a = _gcry_secmem_malloc_internal (newsize); | ||
571 | if (a) | ||
572 | { | ||
573 | memcpy (a, p, size); | ||
574 | memset ((char *) a + size, 0, newsize - size); | ||
575 | _gcry_secmem_free_internal (p); | ||
576 | } | ||
577 | } | ||
578 | |||
579 | SECMEM_UNLOCK; | ||
580 | |||
581 | return a; | ||
582 | } | ||
583 | |||
584 | int | ||
585 | _gcry_private_is_secure (const void *p) | ||
586 | { | ||
587 | int ret = 0; | ||
588 | |||
589 | SECMEM_LOCK; | ||
590 | |||
591 | if (pool_okay && BLOCK_VALID (ADDR_TO_BLOCK (p))) | ||
592 | ret = 1; | ||
593 | |||
594 | SECMEM_UNLOCK; | ||
595 | |||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | |||
600 | /**************** | ||
601 | * Warning: This code might be called by an interrupt handler | ||
602 | * and frankly, there should really be such a handler, | ||
603 | * to make sure that the memory is wiped out. | ||
604 | * We hope that the OS wipes out mlocked memory after | ||
605 | * receiving a SIGKILL - it really should do so, otherwise | ||
606 | * there is no chance to get the secure memory cleaned. | ||
607 | */ | ||
608 | void | ||
609 | _gcry_secmem_term () | ||
610 | { | ||
611 | if (!pool_okay) | ||
612 | return; | ||
613 | |||
614 | wipememory2 (pool, 0xff, pool_size); | ||
615 | wipememory2 (pool, 0xaa, pool_size); | ||
616 | wipememory2 (pool, 0x55, pool_size); | ||
617 | wipememory2 (pool, 0x00, pool_size); | ||
618 | #if HAVE_MMAP | ||
619 | if (pool_is_mmapped) | ||
620 | munmap (pool, pool_size); | ||
621 | #endif | ||
622 | pool = NULL; | ||
623 | pool_okay = 0; | ||
624 | pool_size = 0; | ||
625 | } | ||
626 | |||
627 | |||
628 | void | ||
629 | _gcry_secmem_dump_stats () | ||
630 | { | ||
631 | #if 1 | ||
632 | SECMEM_LOCK; | ||
633 | |||
634 | if (pool_okay) | ||
635 | log_info ("secmem usage: %u/%lu bytes in %u blocks\n", | ||
636 | cur_alloced, (unsigned long)pool_size, cur_blocks); | ||
637 | SECMEM_UNLOCK; | ||
638 | #else | ||
639 | memblock_t *mb; | ||
640 | int i; | ||
641 | |||
642 | SECMEM_LOCK; | ||
643 | |||
644 | for (i = 0, mb = (memblock_t *) pool; | ||
645 | BLOCK_VALID (mb); | ||
646 | mb = mb_get_next (mb), i++) | ||
647 | log_info ("SECMEM: [%s] block: %i; size: %i\n", | ||
648 | (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free", | ||
649 | i, | ||
650 | mb->size); | ||
651 | SECMEM_UNLOCK; | ||
652 | #endif | ||
653 | } | ||