LCOV - code coverage report
Current view: top level - src - stdmem.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 20 78 25.6 %
Date: 2016-09-12 12:56:58 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /* stdmem.c  -  private memory allocator
       2             :  * Copyright (C) 1998, 2000, 2002, 2005, 2008 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser general Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /*
      21             :  * Description of the layered memory management in Libgcrypt:
      22             :  *
      23             :  *                                  [User]
      24             :  *                                    |
      25             :  *                                    |
      26             :  *                                   \ /
      27             :  *                   global.c: [MM entrance points]   -----> [user callbacks]
      28             :  *                               |          |
      29             :  *                               |          |
      30             :  *                              \ /        \ /
      31             :  *
      32             :  *      stdmem.c: [non-secure handlers] [secure handlers]
      33             :  *
      34             :  *                               |         |
      35             :  *                               |         |
      36             :  *                              \ /       \ /
      37             :  *
      38             :  *                  stdmem.c: [ memory guard ]
      39             :  *
      40             :  *                               |         |
      41             :  *                               |         |
      42             :  *                              \ /       \ /
      43             :  *
      44             :  *           libc: [ MM functions ]     secmem.c: [ secure MM functions]
      45             :  */
      46             : 
      47             : #include <config.h>
      48             : #include <stdio.h>
      49             : #include <stdlib.h>
      50             : #include <string.h>
      51             : #include <stdarg.h>
      52             : #include <errno.h>
      53             : 
      54             : #include "g10lib.h"
      55             : #include "stdmem.h"
      56             : #include "secmem.h"
      57             : 
      58             : 
      59             : 
      60             : #define MAGIC_NOR_BYTE 0x55
      61             : #define MAGIC_SEC_BYTE 0xcc
      62             : #define MAGIC_END_BYTE 0xaa
      63             : 
      64             : #if SIZEOF_UNSIGNED_LONG == 8
      65             : #define EXTRA_ALIGN 4
      66             : #else
      67             : #define EXTRA_ALIGN 0
      68             : #endif
      69             : 
      70             : 
      71             : static int use_m_guard = 0;
      72             : 
      73             : /****************
      74             :  * Warning: Never use this function after any of the functions
      75             :  * here have been used.
      76             :  */
      77             : void
      78           0 : _gcry_private_enable_m_guard (void)
      79             : {
      80           0 :   use_m_guard = 1;
      81           0 : }
      82             : 
      83             : 
      84             : /*
      85             :  * Allocate memory of size n.
      86             :  * Return NULL if we are out of memory.
      87             :  */
      88             : void *
      89    89081122 : _gcry_private_malloc (size_t n)
      90             : {
      91    89081122 :   if (!n)
      92             :     {
      93           0 :       gpg_err_set_errno (EINVAL);
      94           0 :       return NULL; /* Allocating 0 bytes is undefined - we better return
      95             :                       an error to detect such coding errors.  */
      96             :     }
      97             : 
      98    89081122 :   if (use_m_guard)
      99             :     {
     100             :       char *p;
     101             : 
     102           0 :       if ( !(p = malloc (n + EXTRA_ALIGN+5)) )
     103           0 :         return NULL;
     104           0 :       ((byte*)p)[EXTRA_ALIGN+0] = n;
     105           0 :       ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
     106           0 :       ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
     107           0 :       ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE;
     108           0 :       p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
     109           0 :       return p+EXTRA_ALIGN+4;
     110             :     }
     111             :   else
     112             :     {
     113    89081122 :       return malloc( n );
     114             :     }
     115             : }
     116             : 
     117             : 
     118             : /*
     119             :  * Allocate memory of size N from the secure memory pool.  Return NULL
     120             :  * if we are out of memory.
     121             :  */
     122             : void *
     123           3 : _gcry_private_malloc_secure (size_t n)
     124             : {
     125           3 :   if (!n)
     126             :     {
     127           0 :       gpg_err_set_errno (EINVAL);
     128           0 :       return NULL; /* Allocating 0 bytes is undefined - better return an
     129             :                       error to detect such coding errors.  */
     130             :     }
     131             : 
     132           3 :   if (use_m_guard)
     133             :     {
     134             :       char *p;
     135             : 
     136           0 :       if ( !(p = _gcry_secmem_malloc (n +EXTRA_ALIGN+ 5)) )
     137           0 :         return NULL;
     138           0 :       ((byte*)p)[EXTRA_ALIGN+0] = n;
     139           0 :       ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
     140           0 :       ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
     141           0 :       ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE;
     142           0 :       p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
     143           0 :       return p+EXTRA_ALIGN+4;
     144             :     }
     145             :   else
     146             :     {
     147           3 :       return _gcry_secmem_malloc( n );
     148             :     }
     149             : }
     150             : 
     151             : 
     152             : /*
     153             :  * Realloc and clear the old space
     154             :  * Return NULL if there is not enough memory.
     155             :  */
     156             : void *
     157      207248 : _gcry_private_realloc ( void *a, size_t n )
     158             : {
     159      207248 :   if (use_m_guard)
     160             :     {
     161           0 :       unsigned char *p = a;
     162             :       char *b;
     163             :       size_t len;
     164             : 
     165           0 :       if (!a)
     166           0 :         return _gcry_private_malloc(n);
     167             : 
     168           0 :       _gcry_private_check_heap(p);
     169           0 :       len  = p[-4];
     170           0 :       len |= p[-3] << 8;
     171           0 :       len |= p[-2] << 16;
     172           0 :       if( len >= n ) /* We don't shrink for now. */
     173           0 :         return a;
     174           0 :       if (p[-1] == MAGIC_SEC_BYTE)
     175           0 :         b = _gcry_private_malloc_secure(n);
     176             :       else
     177           0 :         b = _gcry_private_malloc(n);
     178           0 :       if (!b)
     179           0 :         return NULL;
     180           0 :       memcpy (b, a, len);
     181           0 :       memset (b+len, 0, n-len);
     182           0 :       _gcry_private_free (p);
     183           0 :       return b;
     184             :     }
     185      207248 :   else if ( _gcry_private_is_secure(a) )
     186             :     {
     187           0 :       return _gcry_secmem_realloc( a, n );
     188             :     }
     189             :   else
     190             :     {
     191      207248 :       return realloc( a, n );
     192             :     }
     193             : }
     194             : 
     195             : 
     196             : void
     197           0 : _gcry_private_check_heap (const void *a)
     198             : {
     199           0 :   if (use_m_guard)
     200             :     {
     201           0 :       const byte *p = a;
     202             :       size_t len;
     203             : 
     204           0 :       if (!p)
     205           0 :         return;
     206             : 
     207           0 :       if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
     208           0 :         _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]);
     209           0 :       len  = p[-4];
     210           0 :       len |= p[-3] << 8;
     211           0 :       len |= p[-2] << 16;
     212           0 :       if ( p[len] != MAGIC_END_BYTE )
     213           0 :         _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]);
     214             :     }
     215             : }
     216             : 
     217             : 
     218             : /*
     219             :  * Free a memory block allocated by this or the secmem module
     220             :  */
     221             : void
     222    89079824 : _gcry_private_free (void *a)
     223             : {
     224    89079824 :   unsigned char *p = a;
     225             : 
     226    89079824 :   if (!p)
     227    89079824 :     return;
     228    89079824 :   if (use_m_guard )
     229             :     {
     230           0 :       _gcry_private_check_heap(p);
     231           0 :       if ( _gcry_private_is_secure(a) )
     232           0 :         _gcry_secmem_free(p-EXTRA_ALIGN-4);
     233             :       else
     234             :         {
     235           0 :           free(p-EXTRA_ALIGN-4);
     236             :         }
     237             :     }
     238    89079824 :   else if ( _gcry_private_is_secure(a) )
     239           2 :     _gcry_secmem_free(p);
     240             :   else
     241    89079822 :     free(p);
     242             : }

Generated by: LCOV version 1.11