LCOV - code coverage report
Current view: top level - home/mbr/git/openssl.git/crypto - mem_dbg.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 178 263 67.7 %
Date: 2014-08-02 Functions: 20 27 74.1 %
Branches: 85 135 63.0 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/mem_dbg.c */
       2                 :            : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3                 :            :  * All rights reserved.
       4                 :            :  *
       5                 :            :  * This package is an SSL implementation written
       6                 :            :  * by Eric Young (eay@cryptsoft.com).
       7                 :            :  * The implementation was written so as to conform with Netscapes SSL.
       8                 :            :  * 
       9                 :            :  * This library is free for commercial and non-commercial use as long as
      10                 :            :  * the following conditions are aheared to.  The following conditions
      11                 :            :  * apply to all code found in this distribution, be it the RC4, RSA,
      12                 :            :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13                 :            :  * included with this distribution is covered by the same copyright terms
      14                 :            :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15                 :            :  * 
      16                 :            :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17                 :            :  * the code are not to be removed.
      18                 :            :  * If this package is used in a product, Eric Young should be given attribution
      19                 :            :  * as the author of the parts of the library used.
      20                 :            :  * This can be in the form of a textual message at program startup or
      21                 :            :  * in documentation (online or textual) provided with the package.
      22                 :            :  * 
      23                 :            :  * Redistribution and use in source and binary forms, with or without
      24                 :            :  * modification, are permitted provided that the following conditions
      25                 :            :  * are met:
      26                 :            :  * 1. Redistributions of source code must retain the copyright
      27                 :            :  *    notice, this list of conditions and the following disclaimer.
      28                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      29                 :            :  *    notice, this list of conditions and the following disclaimer in the
      30                 :            :  *    documentation and/or other materials provided with the distribution.
      31                 :            :  * 3. All advertising materials mentioning features or use of this software
      32                 :            :  *    must display the following acknowledgement:
      33                 :            :  *    "This product includes cryptographic software written by
      34                 :            :  *     Eric Young (eay@cryptsoft.com)"
      35                 :            :  *    The word 'cryptographic' can be left out if the rouines from the library
      36                 :            :  *    being used are not cryptographic related :-).
      37                 :            :  * 4. If you include any Windows specific code (or a derivative thereof) from 
      38                 :            :  *    the apps directory (application code) you must include an acknowledgement:
      39                 :            :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40                 :            :  * 
      41                 :            :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51                 :            :  * SUCH DAMAGE.
      52                 :            :  * 
      53                 :            :  * The licence and distribution terms for any publically available version or
      54                 :            :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55                 :            :  * copied and put under another distribution licence
      56                 :            :  * [including the GNU Public Licence.]
      57                 :            :  */
      58                 :            : /* ====================================================================
      59                 :            :  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
      60                 :            :  *
      61                 :            :  * Redistribution and use in source and binary forms, with or without
      62                 :            :  * modification, are permitted provided that the following conditions
      63                 :            :  * are met:
      64                 :            :  *
      65                 :            :  * 1. Redistributions of source code must retain the above copyright
      66                 :            :  *    notice, this list of conditions and the following disclaimer. 
      67                 :            :  *
      68                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      69                 :            :  *    notice, this list of conditions and the following disclaimer in
      70                 :            :  *    the documentation and/or other materials provided with the
      71                 :            :  *    distribution.
      72                 :            :  *
      73                 :            :  * 3. All advertising materials mentioning features or use of this
      74                 :            :  *    software must display the following acknowledgment:
      75                 :            :  *    "This product includes software developed by the OpenSSL Project
      76                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      77                 :            :  *
      78                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      79                 :            :  *    endorse or promote products derived from this software without
      80                 :            :  *    prior written permission. For written permission, please contact
      81                 :            :  *    openssl-core@openssl.org.
      82                 :            :  *
      83                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      84                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      85                 :            :  *    permission of the OpenSSL Project.
      86                 :            :  *
      87                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      88                 :            :  *    acknowledgment:
      89                 :            :  *    "This product includes software developed by the OpenSSL Project
      90                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      91                 :            :  *
      92                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      93                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      94                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      95                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      96                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      97                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      98                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      99                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     100                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     101                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     102                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     103                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
     104                 :            :  * ====================================================================
     105                 :            :  *
     106                 :            :  * This product includes cryptographic software written by Eric Young
     107                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
     108                 :            :  * Hudson (tjh@cryptsoft.com).
     109                 :            :  *
     110                 :            :  */
     111                 :            : 
     112                 :            : #include <stdio.h>
     113                 :            : #include <stdlib.h>
     114                 :            : #include <time.h> 
     115                 :            : #include "cryptlib.h"
     116                 :            : #include <openssl/crypto.h>
     117                 :            : #include <openssl/buffer.h>
     118                 :            : #include <openssl/bio.h>
     119                 :            : #include <openssl/lhash.h>
     120                 :            : 
     121                 :            : static int mh_mode=CRYPTO_MEM_CHECK_OFF;
     122                 :            : /* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
     123                 :            :  * when the application asks for it (usually after library initialisation
     124                 :            :  * for which no book-keeping is desired).
     125                 :            :  *
     126                 :            :  * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
     127                 :            :  * thinks that certain allocations should not be checked (e.g. the data
     128                 :            :  * structures used for memory checking).  It is not suitable as an initial
     129                 :            :  * state: the library will unexpectedly enable memory checking when it
     130                 :            :  * executes one of those sections that want to disable checking
     131                 :            :  * temporarily.
     132                 :            :  *
     133                 :            :  * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
     134                 :            :  */
     135                 :            : 
     136                 :            : static unsigned long order = 0; /* number of memory requests */
     137                 :            : 
     138                 :            : DECLARE_LHASH_OF(MEM);
     139                 :            : static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests
     140                 :            :                                 * (address as key); access requires
     141                 :            :                                 * MALLOC2 lock */
     142                 :            : 
     143                 :            : 
     144                 :            : typedef struct app_mem_info_st
     145                 :            : /* For application-defined information (static C-string `info')
     146                 :            :  * to be displayed in memory leak list.
     147                 :            :  * Each thread has its own stack.  For applications, there is
     148                 :            :  *   CRYPTO_push_info("...")     to push an entry,
     149                 :            :  *   CRYPTO_pop_info()           to pop an entry,
     150                 :            :  *   CRYPTO_remove_all_info()    to pop all entries.
     151                 :            :  */
     152                 :            :         {
     153                 :            :         CRYPTO_THREADID threadid;
     154                 :            :         const char *file;
     155                 :            :         int line;
     156                 :            :         const char *info;
     157                 :            :         struct app_mem_info_st *next; /* tail of thread's stack */
     158                 :            :         int references;
     159                 :            :         } APP_INFO;
     160                 :            : 
     161                 :            : static void app_info_free(APP_INFO *);
     162                 :            : 
     163                 :            : DECLARE_LHASH_OF(APP_INFO);
     164                 :            : static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those
     165                 :            :                                        * app_mem_info_st's that are at
     166                 :            :                                        * the top of their thread's
     167                 :            :                                        * stack (with `thread' as key);
     168                 :            :                                        * access requires MALLOC2
     169                 :            :                                        * lock */
     170                 :            : 
     171                 :            : typedef struct mem_st
     172                 :            : /* memory-block description */
     173                 :            :         {
     174                 :            :         void *addr;
     175                 :            :         int num;
     176                 :            :         const char *file;
     177                 :            :         int line;
     178                 :            :         CRYPTO_THREADID threadid;
     179                 :            :         unsigned long order;
     180                 :            :         time_t time;
     181                 :            :         APP_INFO *app_info;
     182                 :            :         } MEM;
     183                 :            : 
     184                 :            : static long options =             /* extra information to be recorded */
     185                 :            : #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
     186                 :            :         V_CRYPTO_MDEBUG_TIME |
     187                 :            : #endif
     188                 :            : #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
     189                 :            :         V_CRYPTO_MDEBUG_THREAD |
     190                 :            : #endif
     191                 :            :         0;
     192                 :            : 
     193                 :            : 
     194                 :            : static unsigned int num_disable = 0; /* num_disable > 0
     195                 :            :                                       *     iff
     196                 :            :                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
     197                 :            :                                       */
     198                 :            : 
     199                 :            : /* Valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in this
     200                 :            :  * case (by the thread named in disabling_thread).
     201                 :            :  */
     202                 :            : static CRYPTO_THREADID disabling_threadid;
     203                 :            : 
     204                 :       6498 : static void app_info_free(APP_INFO *inf)
     205                 :            :         {
     206         [ +  + ]:       6498 :         if (--(inf->references) <= 0)
     207                 :            :                 {
     208         [ -  + ]:       3249 :                 if (inf->next != NULL)
     209                 :            :                         {
     210                 :          0 :                         app_info_free(inf->next);
     211                 :            :                         }
     212                 :       3249 :                 OPENSSL_free(inf);
     213                 :            :                 }
     214                 :       6498 :         }
     215                 :            : 
     216                 :   39433106 : int CRYPTO_mem_ctrl(int mode)
     217                 :            :         {
     218                 :   39433106 :         int ret=mh_mode;
     219                 :            : 
     220                 :   39433106 :         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
     221   [ +  -  +  +  :   39433106 :         switch (mode)
                      - ]
     222                 :            :                 {
     223                 :            :         /* for applications (not to be called while multiple threads
     224                 :            :          * use the library): */
     225                 :            :         case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
     226                 :       1630 :                 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
     227                 :       1630 :                 num_disable = 0;
     228                 :       1630 :                 break;
     229                 :            :         case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
     230                 :          0 :                 mh_mode = 0;
     231                 :          0 :                 num_disable = 0; /* should be true *before* MemCheck_stop is used,
     232                 :            :                                     or there'll be a lot of confusion */
     233                 :          0 :                 break;
     234                 :            : 
     235                 :            :         /* switch off temporarily (for library-internal use): */
     236                 :            :         case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
     237         [ +  + ]:   19715738 :                 if (mh_mode & CRYPTO_MEM_CHECK_ON)
     238                 :            :                         {
     239                 :            :                         CRYPTO_THREADID cur;
     240                 :   19715737 :                         CRYPTO_THREADID_current(&cur);
     241 [ -  + ][ #  # ]:   19715737 :                         if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
     242                 :            :                                 {
     243                 :            :                                 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
     244                 :            :                                  * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
     245                 :            :                                  * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
     246                 :            :                                  * it because we block entry to this function).
     247                 :            :                                  * Give them a chance, first, and then claim the locks in
     248                 :            :                                  * appropriate order (long-time lock first).
     249                 :            :                                  */
     250                 :   19715737 :                                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
     251                 :            :                                 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
     252                 :            :                                  * and CRYPTO_LOCK_MALLOC, we'll still be in the right
     253                 :            :                                  * "case" and "if" branch because MemCheck_start and
     254                 :            :                                  * MemCheck_stop may never be used while there are multiple
     255                 :            :                                  * OpenSSL threads. */
     256                 :   19715737 :                                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
     257                 :   19715737 :                                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
     258                 :   19715737 :                                 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
     259                 :   19715737 :                                 CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
     260                 :            :                                 }
     261                 :   19715737 :                         num_disable++;
     262                 :            :                         }
     263                 :            :                 break;
     264                 :            :         case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
     265         [ +  + ]:   19715738 :                 if (mh_mode & CRYPTO_MEM_CHECK_ON)
     266                 :            :                         {
     267         [ +  - ]:   19715737 :                         if (num_disable) /* always true, or something is going wrong */
     268                 :            :                                 {
     269                 :   19715737 :                                 num_disable--;
     270         [ +  - ]:   19715737 :                                 if (num_disable == 0)
     271                 :            :                                         {
     272                 :   19715737 :                                         mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
     273                 :   19715737 :                                         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
     274                 :            :                                         }
     275                 :            :                                 }
     276                 :            :                         }
     277                 :            :                 break;
     278                 :            : 
     279                 :            :         default:
     280                 :            :                 break;
     281                 :            :                 }
     282                 :   39433106 :         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
     283                 :   39433106 :         return(ret);
     284                 :            :         }
     285                 :            : 
     286                 :   59141812 : int CRYPTO_is_mem_check_on(void)
     287                 :            :         {
     288                 :   59141812 :         int ret = 0;
     289                 :            : 
     290         [ +  + ]:   59141812 :         if (mh_mode & CRYPTO_MEM_CHECK_ON)
     291                 :            :                 {
     292                 :            :                 CRYPTO_THREADID cur;
     293                 :   59134694 :                 CRYPTO_THREADID_current(&cur);
     294                 :   59134694 :                 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
     295                 :            : 
     296                 :  118269388 :                 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
     297 [ +  + ][ -  + ]:   59134694 :                         || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
     298                 :            : 
     299                 :   59134694 :                 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
     300                 :            :                 }
     301                 :   59141812 :         return(ret);
     302                 :            :         }       
     303                 :            : 
     304                 :            : 
     305                 :       1629 : void CRYPTO_dbg_set_options(long bits)
     306                 :            :         {
     307                 :       1629 :         options = bits;
     308                 :       1629 :         }
     309                 :            : 
     310                 :          0 : long CRYPTO_dbg_get_options(void)
     311                 :            :         {
     312                 :          0 :         return options;
     313                 :            :         }
     314                 :            : 
     315                 :   19729184 : static int mem_cmp(const MEM *a, const MEM *b)
     316                 :            :         {
     317                 :            : #ifdef _WIN64
     318                 :            :         const char *ap=(const char *)a->addr,
     319                 :            :                    *bp=(const char *)b->addr;
     320                 :            :         if (ap==bp)     return 0;
     321                 :            :         else if (ap>bp)      return 1;
     322                 :            :         else            return -1;
     323                 :            : #else
     324                 :    9864592 :         return (const char *)a->addr - (const char *)b->addr;
     325                 :            : #endif
     326                 :            :         }
     327                 :   19729184 : static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
     328                 :            : 
     329                 :   39516408 : static unsigned long mem_hash(const MEM *a)
     330                 :            :         {
     331                 :            :         unsigned long ret;
     332                 :            : 
     333                 :   19758204 :         ret=(unsigned long)a->addr;
     334                 :            : 
     335                 :   19758204 :         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
     336                 :   19758204 :         return(ret);
     337                 :            :         }
     338                 :   39516408 : static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
     339                 :            : 
     340                 :            : /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
     341                 :      28536 : static int app_info_cmp(const void *a_void, const void *b_void)
     342                 :            :         {
     343                 :      28536 :         return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
     344                 :            :                                 &((const APP_INFO *)b_void)->threadid);
     345                 :            :         }
     346                 :      57072 : static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
     347                 :            : 
     348                 :    9681131 : static unsigned long app_info_hash(const APP_INFO *a)
     349                 :            :         {
     350                 :            :         unsigned long ret;
     351                 :            : 
     352                 :    9681131 :         ret = CRYPTO_THREADID_hash(&a->threadid);
     353                 :            :         /* This is left in as a "who am I to question legacy?" measure */
     354                 :    9681131 :         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
     355                 :    9681131 :         return(ret);
     356                 :            :         }
     357                 :   19362262 : static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
     358                 :            : 
     359                 :      22036 : static APP_INFO *pop_info(void)
     360                 :            :         {
     361                 :            :         APP_INFO tmp;
     362                 :      22036 :         APP_INFO *ret = NULL;
     363                 :            : 
     364         [ +  - ]:      22036 :         if (amih != NULL)
     365                 :            :                 {
     366                 :      22036 :                 CRYPTO_THREADID_current(&tmp.threadid);
     367         [ +  - ]:      22036 :                 if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
     368                 :            :                         {
     369                 :      22036 :                         APP_INFO *next=ret->next;
     370                 :            : 
     371         [ -  + ]:      22036 :                         if (next != NULL)
     372                 :            :                                 {
     373                 :          0 :                                 next->references++;
     374                 :          0 :                                 (void)lh_APP_INFO_insert(amih,next);
     375                 :            :                                 }
     376                 :            : #ifdef LEVITTE_DEBUG_MEM
     377                 :            :                         if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
     378                 :            :                                 {
     379                 :            :                                 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
     380                 :            :                                         CRYPTO_THREADID_hash(&ret->threadid),
     381                 :            :                                         CRYPTO_THREADID_hash(&tmp.threadid));
     382                 :            :                                 abort();
     383                 :            :                                 }
     384                 :            : #endif
     385         [ +  + ]:      22036 :                         if (--(ret->references) <= 0)
     386                 :            :                                 {
     387                 :      18786 :                                 ret->next = NULL;
     388         [ -  + ]:      18786 :                                 if (next != NULL)
     389                 :          0 :                                         next->references--;
     390                 :      18786 :                                 OPENSSL_free(ret);
     391                 :            :                                 }
     392                 :            :                         }
     393                 :            :                 }
     394                 :      22036 :         return(ret);
     395                 :            :         }
     396                 :            : 
     397                 :      22340 : int CRYPTO_push_info_(const char *info, const char *file, int line)
     398                 :            :         {
     399                 :            :         APP_INFO *ami, *amim;
     400                 :      22340 :         int ret=0;
     401                 :            : 
     402         [ +  + ]:      22340 :         if (is_MemCheck_on())
     403                 :            :                 {
     404                 :      22036 :                 MemCheck_off(); /* obtain MALLOC2 lock */
     405                 :            : 
     406         [ +  - ]:      22036 :                 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
     407                 :            :                         {
     408                 :            :                         ret=0;
     409                 :            :                         goto err;
     410                 :            :                         }
     411         [ +  + ]:      22036 :                 if (amih == NULL)
     412                 :            :                         {
     413         [ -  + ]:       1629 :                         if ((amih=lh_APP_INFO_new()) == NULL)
     414                 :            :                                 {
     415                 :          0 :                                 OPENSSL_free(ami);
     416                 :          0 :                                 ret=0;
     417                 :          0 :                                 goto err;
     418                 :            :                                 }
     419                 :            :                         }
     420                 :            : 
     421                 :      22036 :                 CRYPTO_THREADID_current(&ami->threadid);
     422                 :      22036 :                 ami->file=file;
     423                 :      22036 :                 ami->line=line;
     424                 :      22036 :                 ami->info=info;
     425                 :      22036 :                 ami->references=1;
     426                 :      22036 :                 ami->next=NULL;
     427                 :            : 
     428         [ -  + ]:      22036 :                 if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
     429                 :            :                         {
     430                 :            : #ifdef LEVITTE_DEBUG_MEM
     431                 :            :                         if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
     432                 :            :                                 {
     433                 :            :                                 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
     434                 :            :                                         CRYPTO_THREADID_hash(&amim->threadid),
     435                 :            :                                         CRYPTO_THREADID_hash(&ami->threadid));
     436                 :            :                                 abort();
     437                 :            :                                 }
     438                 :            : #endif
     439                 :          0 :                         ami->next=amim;
     440                 :            :                         }
     441                 :            :  err:
     442                 :      22036 :                 MemCheck_on(); /* release MALLOC2 lock */
     443                 :            :                 }
     444                 :            : 
     445                 :      22340 :         return(ret);
     446                 :            :         }
     447                 :            : 
     448                 :      22340 : int CRYPTO_pop_info(void)
     449                 :            :         {
     450                 :      22340 :         int ret=0;
     451                 :            : 
     452         [ +  + ]:      22340 :         if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
     453                 :            :                 {
     454                 :      22036 :                 MemCheck_off(); /* obtain MALLOC2 lock */
     455                 :            : 
     456                 :      22036 :                 ret=(pop_info() != NULL);
     457                 :            : 
     458                 :      22036 :                 MemCheck_on(); /* release MALLOC2 lock */
     459                 :            :                 }
     460                 :      22340 :         return(ret);
     461                 :            :         }
     462                 :            : 
     463                 :          0 : int CRYPTO_remove_all_info(void)
     464                 :            :         {
     465                 :          0 :         int ret=0;
     466                 :            : 
     467         [ #  # ]:          0 :         if (is_MemCheck_on()) /* _must_ be true */
     468                 :            :                 {
     469                 :          0 :                 MemCheck_off(); /* obtain MALLOC2 lock */
     470                 :            : 
     471         [ #  # ]:          0 :                 while(pop_info() != NULL)
     472                 :          0 :                         ret++;
     473                 :            : 
     474                 :          0 :                 MemCheck_on(); /* release MALLOC2 lock */
     475                 :            :                 }
     476                 :          0 :         return(ret);
     477                 :            :         }
     478                 :            : 
     479                 :            : 
     480                 :            : static unsigned long break_order_num=0;
     481                 :   59002962 : void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
     482                 :            :         int before_p)
     483                 :            :         {
     484                 :            :         MEM *m,*mm;
     485                 :            :         APP_INFO tmp,*amim;
     486                 :            : 
     487         [ +  + ]:   59002962 :         switch(before_p & 127)
     488                 :            :                 {
     489                 :            :         case 0:
     490                 :            :                 break;
     491                 :            :         case 1:
     492         [ +  - ]:   29501481 :                 if (addr == NULL)
     493                 :            :                         break;
     494                 :            : 
     495         [ +  + ]:   29501481 :                 if (is_MemCheck_on())
     496                 :            :                         {
     497                 :    9783569 :                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
     498         [ -  + ]:    9783569 :                         if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
     499                 :            :                                 {
     500                 :          0 :                                 OPENSSL_free(addr);
     501                 :          0 :                                 MemCheck_on(); /* release MALLOC2 lock
     502                 :            :                                                 * if num_disabled drops to 0 */
     503                 :          0 :                                 return;
     504                 :            :                                 }
     505         [ +  + ]:    9783569 :                         if (mh == NULL)
     506                 :            :                                 {
     507         [ -  + ]:       3250 :                                 if ((mh=lh_MEM_new()) == NULL)
     508                 :            :                                         {
     509                 :          0 :                                         OPENSSL_free(addr);
     510                 :          0 :                                         OPENSSL_free(m);
     511                 :          0 :                                         addr=NULL;
     512                 :          0 :                                         goto err;
     513                 :            :                                         }
     514                 :            :                                 }
     515                 :            : 
     516                 :    9783569 :                         m->addr=addr;
     517                 :    9783569 :                         m->file=file;
     518                 :    9783569 :                         m->line=line;
     519                 :    9783569 :                         m->num=num;
     520         [ +  - ]:    9783569 :                         if (options & V_CRYPTO_MDEBUG_THREAD)
     521                 :    9783569 :                                 CRYPTO_THREADID_current(&m->threadid);
     522                 :            :                         else
     523                 :          0 :                                 memset(&m->threadid, 0, sizeof(m->threadid));
     524                 :            : 
     525         [ +  + ]:    9783569 :                         if (order == break_order_num)
     526                 :            :                                 {
     527                 :            :                                 /* BREAK HERE */
     528                 :       1629 :                                 m->order=order;
     529                 :            :                                 }
     530                 :    9783569 :                         m->order=order++;
     531                 :            : #ifdef LEVITTE_DEBUG_MEM
     532                 :            :                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
     533                 :            :                                 m->order,
     534                 :            :                                 (before_p & 128) ? '*' : '+',
     535                 :            :                                 m->addr, m->num);
     536                 :            : #endif
     537         [ +  - ]:    9783569 :                         if (options & V_CRYPTO_MDEBUG_TIME)
     538                 :    9783569 :                                 m->time=time(NULL);
     539                 :            :                         else
     540                 :          0 :                                 m->time=0;
     541                 :            : 
     542                 :    9783569 :                         CRYPTO_THREADID_current(&tmp.threadid);
     543                 :    9783569 :                         m->app_info=NULL;
     544         [ +  + ]:    9783569 :                         if (amih != NULL
     545         [ +  + ]:    9637059 :                             && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
     546                 :            :                                 {
     547                 :       6500 :                                 m->app_info = amim;
     548                 :       6500 :                                 amim->references++;
     549                 :            :                                 }
     550                 :            : 
     551         [ -  + ]:    9783569 :                         if ((mm=lh_MEM_insert(mh, m)) != NULL)
     552                 :            :                                 {
     553                 :            :                                 /* Not good, but don't sweat it */
     554         [ #  # ]:          0 :                                 if (mm->app_info != NULL)
     555                 :            :                                         {
     556                 :          0 :                                         mm->app_info->references--;
     557                 :            :                                         }
     558                 :          0 :                                 OPENSSL_free(mm);
     559                 :            :                                 }
     560                 :            :                 err:
     561                 :    9783569 :                         MemCheck_on(); /* release MALLOC2 lock
     562                 :            :                                         * if num_disabled drops to 0 */
     563                 :            :                         }
     564                 :            :                 break;
     565                 :            :                 }
     566                 :            :         return;
     567                 :            :         }
     568                 :            : 
     569                 :   58970748 : void CRYPTO_dbg_free(void *addr, int before_p)
     570                 :            :         {
     571                 :            :         MEM m,*mp;
     572                 :            : 
     573         [ +  + ]:   58970748 :         switch(before_p)
     574                 :            :                 {
     575                 :            :         case 0:
     576         [ +  + ]:   29485374 :                 if (addr == NULL)
     577                 :            :                         break;
     578                 :            : 
     579 [ +  + ][ +  + ]:   29478393 :                 if (is_MemCheck_on() && (mh != NULL))
     580                 :            :                         {
     581                 :    9788420 :                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
     582                 :            : 
     583                 :    9788420 :                         m.addr=addr;
     584                 :    9788420 :                         mp=lh_MEM_delete(mh,&m);
     585         [ +  + ]:    9788420 :                         if (mp != NULL)
     586                 :            :                                 {
     587                 :            : #ifdef LEVITTE_DEBUG_MEM
     588                 :            :                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
     589                 :            :                                 mp->order, mp->addr, mp->num);
     590                 :            : #endif
     591         [ +  + ]:    9773829 :                                 if (mp->app_info != NULL)
     592                 :       6498 :                                         app_info_free(mp->app_info);
     593                 :    9773829 :                                 OPENSSL_free(mp);
     594                 :            :                                 }
     595                 :            : 
     596                 :    9788420 :                         MemCheck_on(); /* release MALLOC2 lock
     597                 :            :                                         * if num_disabled drops to 0 */
     598                 :            :                         }
     599                 :            :                 break;
     600                 :            :         case 1:
     601                 :            :                 break;
     602                 :            :                 }
     603                 :   58970748 :         }
     604                 :            : 
     605                 :     234516 : void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
     606                 :            :         const char *file, int line, int before_p)
     607                 :            :         {
     608                 :            :         MEM m,*mp;
     609                 :            : 
     610                 :            : #ifdef LEVITTE_DEBUG_MEM
     611                 :            :         fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
     612                 :            :                 addr1, addr2, num, file, line, before_p);
     613                 :            : #endif
     614                 :            : 
     615         [ +  + ]:     234516 :         switch(before_p)
     616                 :            :                 {
     617                 :            :         case 0:
     618                 :            :                 break;
     619                 :            :         case 1:
     620         [ +  - ]:     117258 :                 if (addr2 == NULL)
     621                 :            :                         break;
     622                 :            : 
     623         [ -  + ]:     117258 :                 if (addr1 == NULL)
     624                 :            :                         {
     625                 :          0 :                         CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
     626                 :          0 :                         break;
     627                 :            :                         }
     628                 :            : 
     629         [ +  + ]:     117258 :                 if (is_MemCheck_on())
     630                 :            :                         {
     631                 :      95452 :                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
     632                 :            : 
     633                 :      95452 :                         m.addr=addr1;
     634                 :      95452 :                         mp=lh_MEM_delete(mh,&m);
     635         [ +  + ]:      95452 :                         if (mp != NULL)
     636                 :            :                                 {
     637                 :            : #ifdef LEVITTE_DEBUG_MEM
     638                 :            :                                 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
     639                 :            :                                         mp->order,
     640                 :            :                                         mp->addr, mp->num,
     641                 :            :                                         addr2, num);
     642                 :            : #endif
     643                 :      90763 :                                 mp->addr=addr2;
     644                 :      90763 :                                 mp->num=num;
     645                 :      90763 :                                 (void)lh_MEM_insert(mh,mp);
     646                 :            :                                 }
     647                 :            : 
     648                 :      95452 :                         MemCheck_on(); /* release MALLOC2 lock
     649                 :            :                                         * if num_disabled drops to 0 */
     650                 :            :                         }
     651                 :            :                 break;
     652                 :            :                 }
     653                 :     234516 :         return;
     654                 :            :         }
     655                 :            : 
     656                 :            : 
     657                 :            : typedef struct mem_leak_st
     658                 :            :         {
     659                 :            :         BIO *bio;
     660                 :            :         int chunks;
     661                 :            :         long bytes;
     662                 :            :         } MEM_LEAK;
     663                 :            : 
     664                 :          0 : static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
     665                 :            :         {
     666                 :            :         char buf[1024];
     667                 :          0 :         char *bufp = buf;
     668                 :            :         APP_INFO *amip;
     669                 :            :         int ami_cnt;
     670                 :          0 :         struct tm *lcl = NULL;
     671                 :            :         CRYPTO_THREADID ti;
     672                 :            : 
     673                 :            : #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
     674                 :            : 
     675         [ #  # ]:          0 :         if(m->addr == (char *)l->bio)
     676                 :          0 :             return;
     677                 :            : 
     678         [ #  # ]:          0 :         if (options & V_CRYPTO_MDEBUG_TIME)
     679                 :            :                 {
     680                 :          0 :                 lcl = localtime(&m->time);
     681                 :            :         
     682                 :          0 :                 BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
     683                 :            :                         lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
     684                 :          0 :                 bufp += strlen(bufp);
     685                 :            :                 }
     686                 :            : 
     687                 :          0 :         BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
     688                 :            :                 m->order,m->file,m->line);
     689                 :          0 :         bufp += strlen(bufp);
     690                 :            : 
     691         [ #  # ]:          0 :         if (options & V_CRYPTO_MDEBUG_THREAD)
     692                 :            :                 {
     693                 :          0 :                 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
     694                 :            :                         CRYPTO_THREADID_hash(&m->threadid));
     695                 :          0 :                 bufp += strlen(bufp);
     696                 :            :                 }
     697                 :            : 
     698                 :          0 :         BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
     699                 :          0 :                 m->num,(unsigned long)m->addr);
     700                 :          0 :         bufp += strlen(bufp);
     701                 :            : 
     702                 :          0 :         BIO_puts(l->bio,buf);
     703                 :            :         
     704                 :          0 :         l->chunks++;
     705                 :          0 :         l->bytes+=m->num;
     706                 :            : 
     707                 :          0 :         amip=m->app_info;
     708                 :          0 :         ami_cnt=0;
     709         [ #  # ]:          0 :         if (!amip)
     710                 :            :                 return;
     711                 :          0 :         CRYPTO_THREADID_cpy(&ti, &amip->threadid);
     712                 :            : 
     713                 :            :         do
     714                 :            :                 {
     715                 :            :                 int buf_len;
     716                 :            :                 int info_len;
     717                 :            : 
     718                 :          0 :                 ami_cnt++;
     719                 :          0 :                 memset(buf,'>',ami_cnt);
     720                 :          0 :                 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
     721                 :            :                         " thread=%lu, file=%s, line=%d, info=\"",
     722                 :          0 :                         CRYPTO_THREADID_hash(&amip->threadid), amip->file,
     723                 :            :                         amip->line);
     724                 :          0 :                 buf_len=strlen(buf);
     725                 :          0 :                 info_len=strlen(amip->info);
     726         [ #  # ]:          0 :                 if (128 - buf_len - 3 < info_len)
     727                 :            :                         {
     728                 :          0 :                         memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
     729                 :          0 :                         buf_len = 128 - 3;
     730                 :            :                         }
     731                 :            :                 else
     732                 :            :                         {
     733                 :          0 :                         BUF_strlcpy(buf + buf_len, amip->info,
     734                 :            :                                     sizeof buf - buf_len);
     735                 :          0 :                         buf_len = strlen(buf);
     736                 :            :                         }
     737                 :          0 :                 BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
     738                 :            :                 
     739                 :          0 :                 BIO_puts(l->bio,buf);
     740                 :            : 
     741                 :          0 :                 amip = amip->next;
     742                 :            :                 }
     743 [ #  # ][ #  # ]:          0 :         while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
     744                 :            : 
     745                 :            : #ifdef LEVITTE_DEBUG_MEM
     746                 :            :         if (amip)
     747                 :            :                 {
     748                 :            :                 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
     749                 :            :                 abort();
     750                 :            :                 }
     751                 :            : #endif
     752                 :            :         }
     753                 :            : 
     754                 :          0 : static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
     755                 :            : 
     756                 :       1630 : void CRYPTO_mem_leaks(BIO *b)
     757                 :            :         {
     758                 :            :         MEM_LEAK ml;
     759                 :            : 
     760 [ +  + ][ +  + ]:       1630 :         if (mh == NULL && amih == NULL)
     761                 :          1 :                 return;
     762                 :            : 
     763                 :       1629 :         MemCheck_off(); /* obtain MALLOC2 lock */
     764                 :            : 
     765                 :       1629 :         ml.bio=b;
     766                 :       1629 :         ml.bytes=0;
     767                 :       1629 :         ml.chunks=0;
     768         [ +  + ]:       1629 :         if (mh != NULL)
     769                 :       1628 :                 lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK,
     770                 :            :                                  &ml);
     771         [ -  + ]:       1629 :         if (ml.chunks != 0)
     772                 :            :                 {
     773                 :          0 :                 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
     774                 :            :                            ml.bytes,ml.chunks);
     775                 :            : #ifdef CRYPTO_MDEBUG_ABORT
     776                 :            :                 abort();
     777                 :            : #endif
     778                 :            :                 }
     779                 :            :         else
     780                 :            :                 {
     781                 :            :                 /* Make sure that, if we found no leaks, memory-leak debugging itself
     782                 :            :                  * does not introduce memory leaks (which might irritate
     783                 :            :                  * external debugging tools).
     784                 :            :                  * (When someone enables leak checking, but does not call
     785                 :            :                  * this function, we declare it to be their fault.)
     786                 :            :                  *
     787                 :            :                  * XXX    This should be in CRYPTO_mem_leaks_cb,
     788                 :            :                  * and CRYPTO_mem_leaks should be implemented by
     789                 :            :                  * using CRYPTO_mem_leaks_cb.
     790                 :            :                  * (Also there should be a variant of lh_doall_arg
     791                 :            :                  * that takes a function pointer instead of a void *;
     792                 :            :                  * this would obviate the ugly and illegal
     793                 :            :                  * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
     794                 :            :                  * Otherwise the code police will come and get us.)
     795                 :            :                  */
     796                 :            :                 int old_mh_mode;
     797                 :            : 
     798                 :       1629 :                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
     799                 :            : 
     800                 :            :                 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
     801                 :            :                  * which uses CRYPTO_is_mem_check_on */
     802                 :       1629 :                 old_mh_mode = mh_mode;
     803                 :       1629 :                 mh_mode = CRYPTO_MEM_CHECK_OFF;
     804                 :            : 
     805         [ +  + ]:       1629 :                 if (mh != NULL)
     806                 :            :                         {
     807                 :       1628 :                         lh_MEM_free(mh);
     808                 :       1628 :                         mh = NULL;
     809                 :            :                         }
     810         [ +  + ]:       1629 :                 if (amih != NULL)
     811                 :            :                         {
     812         [ +  - ]:       1628 :                         if (lh_APP_INFO_num_items(amih) == 0) 
     813                 :            :                                 {
     814                 :       1628 :                                 lh_APP_INFO_free(amih);
     815                 :       1628 :                                 amih = NULL;
     816                 :            :                                 }
     817                 :            :                         }
     818                 :            : 
     819                 :       1629 :                 mh_mode = old_mh_mode;
     820                 :       1629 :                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
     821                 :            :                 }
     822                 :       1629 :         MemCheck_on(); /* release MALLOC2 lock */
     823                 :            :         }
     824                 :            : 
     825                 :            : #ifndef OPENSSL_NO_FP_API
     826                 :          6 : void CRYPTO_mem_leaks_fp(FILE *fp)
     827                 :            :         {
     828                 :            :         BIO *b;
     829                 :            : 
     830         [ +  - ]:          6 :         if (mh == NULL) return;
     831                 :            :         /* Need to turn off memory checking when allocated BIOs ... especially
     832                 :            :          * as we're creating them at a time when we're trying to check we've not
     833                 :            :          * left anything un-free()'d!! */
     834                 :          6 :         MemCheck_off();
     835                 :          6 :         b = BIO_new(BIO_s_file());
     836                 :          6 :         MemCheck_on();
     837         [ +  - ]:          6 :         if(!b) return;
     838                 :          6 :         BIO_set_fp(b,fp,BIO_NOCLOSE);
     839                 :          6 :         CRYPTO_mem_leaks(b);
     840                 :          6 :         BIO_free(b);
     841                 :            :         }
     842                 :            : #endif
     843                 :            : 
     844                 :            : 
     845                 :            : 
     846                 :            : /* FIXME: We really don't allow much to the callback.  For example, it has
     847                 :            :    no chance of reaching the info stack for the item it processes.  Should
     848                 :            :    it really be this way?  -- Richard Levitte */
     849                 :            : /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
     850                 :            :  * If this code is restructured, remove the callback type if it is no longer
     851                 :            :  * needed. -- Geoff Thorpe */
     852                 :            : 
     853                 :            : /* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it
     854                 :            :  * is a function pointer and conversion to void * is prohibited. Instead
     855                 :            :  * pass its address
     856                 :            :  */
     857                 :            : 
     858                 :            : typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
     859                 :            : 
     860                 :          0 : static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
     861                 :            :         {
     862                 :          0 :         (*cb)(m->order,m->file,m->line,m->num,m->addr);
     863                 :          0 :         }
     864                 :            : 
     865                 :          0 : static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
     866                 :            : 
     867                 :          0 : void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
     868                 :            :         {
     869         [ #  # ]:          0 :         if (mh == NULL) return;
     870                 :          0 :         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
     871                 :          0 :         lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
     872                 :            :                          &cb);
     873                 :          0 :         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
     874                 :            :         }

Generated by: LCOV version 1.9