LCOV - code coverage report
Current view: top level - src - stdmem.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 18 76 23.7 %
Date: 2017-03-02 16:44:37 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    90880535 : _gcry_private_malloc (size_t n)
      90             : {
      91    90880535 :   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    90880535 :   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    90880535 :       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.  XHINT tells the allocator that the caller
     121             :  * used an xmalloc style call.
     122             :  */
     123             : void *
     124         182 : _gcry_private_malloc_secure (size_t n, int xhint)
     125             : {
     126         182 :   if (!n)
     127             :     {
     128           0 :       gpg_err_set_errno (EINVAL);
     129           0 :       return NULL; /* Allocating 0 bytes is undefined - better return an
     130             :                       error to detect such coding errors.  */
     131             :     }
     132             : 
     133         182 :   if (use_m_guard)
     134             :     {
     135             :       char *p;
     136             : 
     137           0 :       if (!(p = _gcry_secmem_malloc (n + EXTRA_ALIGN + 5, xhint)))
     138           0 :         return NULL;
     139           0 :       ((byte*)p)[EXTRA_ALIGN+0] = n;
     140           0 :       ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
     141           0 :       ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
     142           0 :       ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE;
     143           0 :       p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
     144           0 :       return p+EXTRA_ALIGN+4;
     145             :     }
     146             :   else
     147             :     {
     148         182 :       return _gcry_secmem_malloc (n, xhint);
     149             :     }
     150             : }
     151             : 
     152             : 
     153             : /*
     154             :  * Realloc and clear the old space.  XHINT tells the allocator that
     155             :  * the caller used an xmalloc style call.  Returns NULL if there is
     156             :  * not enough memory.
     157             :  */
     158             : void *
     159      231506 : _gcry_private_realloc (void *a, size_t n, int xhint)
     160             : {
     161      231506 :   if (use_m_guard)
     162             :     {
     163           0 :       unsigned char *p = a;
     164             :       char *b;
     165             :       size_t len;
     166             : 
     167           0 :       if (!a)
     168           0 :         return _gcry_private_malloc(n);
     169             : 
     170           0 :       _gcry_private_check_heap(p);
     171           0 :       len  = p[-4];
     172           0 :       len |= p[-3] << 8;
     173           0 :       len |= p[-2] << 16;
     174           0 :       if( len >= n ) /* We don't shrink for now. */
     175           0 :         return a;
     176           0 :       if (p[-1] == MAGIC_SEC_BYTE)
     177           0 :         b = _gcry_private_malloc_secure (n, xhint);
     178             :       else
     179           0 :         b = _gcry_private_malloc(n);
     180           0 :       if (!b)
     181           0 :         return NULL;
     182           0 :       memcpy (b, a, len);
     183           0 :       memset (b+len, 0, n-len);
     184           0 :       _gcry_private_free (p);
     185           0 :       return b;
     186             :     }
     187      231506 :   else if ( _gcry_private_is_secure(a) )
     188             :     {
     189           0 :       return _gcry_secmem_realloc (a, n, xhint);
     190             :     }
     191             :   else
     192             :     {
     193      231506 :       return realloc( a, n );
     194             :     }
     195             : }
     196             : 
     197             : 
     198             : void
     199           0 : _gcry_private_check_heap (const void *a)
     200             : {
     201           0 :   if (use_m_guard)
     202             :     {
     203           0 :       const byte *p = a;
     204             :       size_t len;
     205             : 
     206           0 :       if (!p)
     207           0 :         return;
     208             : 
     209           0 :       if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
     210           0 :         _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]);
     211           0 :       len  = p[-4];
     212           0 :       len |= p[-3] << 8;
     213           0 :       len |= p[-2] << 16;
     214           0 :       if ( p[len] != MAGIC_END_BYTE )
     215           0 :         _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]);
     216             :     }
     217             : }
     218             : 
     219             : 
     220             : /*
     221             :  * Free a memory block allocated by this or the secmem module
     222             :  */
     223             : void
     224    90879385 : _gcry_private_free (void *a)
     225             : {
     226    90879385 :   unsigned char *p = a;
     227             : 
     228    90879385 :   if (!p)
     229           0 :     return;
     230    90879385 :   if (use_m_guard )
     231             :     {
     232           0 :       _gcry_private_check_heap(p);
     233           0 :       if (! _gcry_secmem_free (p - EXTRA_ALIGN - 4))
     234             :         {
     235           0 :           free (p - EXTRA_ALIGN - 4);
     236             :         }
     237             :     }
     238    90879385 :   else if (!_gcry_secmem_free (p))
     239             :     {
     240    90879205 :       free(p);
     241             :     }
     242             : }

Generated by: LCOV version 1.13