crypto/ex_data.c:390: error: NULL_DEREFERENCE
  pointer `f` last assigned on line 383 could be null and is dereferenced at line 390, column 5.
Showing all 41 steps of the trace


crypto/ex_data.c:369:1: start of procedure CRYPTO_alloc_ex_data()
367.    * function
368.    */
369. > int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
370.                            int idx)
371.   {

crypto/ex_data.c:376:5: 
374.       void *curval;
375.   
376. >     curval = CRYPTO_get_ex_data(ad, idx);
377.   
378.       /* Already there, no need to allocate */

crypto/ex_data.c:424:1: start of procedure CRYPTO_get_ex_data()
  422.    * particular index in the class used by this variable
  423.    */
  424. > void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
  425.   {
  426.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))

crypto/ex_data.c:426:9: Taking true branch
  424.   void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
  425.   {
  426.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))
                 ^
  427.           return NULL;
  428.       return sk_void_value(ad->sk, idx);

crypto/ex_data.c:427:9: 
  425.   {
  426.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))
  427. >         return NULL;
  428.       return sk_void_value(ad->sk, idx);
  429.   }

crypto/ex_data.c:429:1: return from a call to CRYPTO_get_ex_data
  427.           return NULL;
  428.       return sk_void_value(ad->sk, idx);
  429. > }

crypto/ex_data.c:379:9: Taking false branch
377.   
378.       /* Already there, no need to allocate */
379.       if (curval != NULL)
               ^
380.           return 1;
381.   

crypto/ex_data.c:382:5: 
380.           return 1;
381.   
382. >     ip = get_and_lock(class_index);
383.       f = sk_EX_CALLBACK_value(ip->meth, idx);
384.       CRYPTO_THREAD_unlock(ex_data_lock);

crypto/ex_data.c:50:1: start of procedure get_and_lock()
  48.    * a given class.  On success, *holds the lock.*
  49.    */
  50. > static EX_CALLBACKS *get_and_lock(int class_index)
  51.   {
  52.       EX_CALLBACKS *ip;

crypto/ex_data.c:54:9: Taking false branch
  52.       EX_CALLBACKS *ip;
  53.   
  54.       if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
                ^
  55.           CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
  56.           return NULL;

crypto/ex_data.c:54:28: Taking false branch
  52.       EX_CALLBACKS *ip;
  53.   
  54.       if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
                                   ^
  55.           CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
  56.           return NULL;

crypto/ex_data.c:59:10: 
  57.       }
  58.   
  59. >     if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
  60.           CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
  61.           return NULL;

crypto/threads_pthread.c:111:1: start of procedure CRYPTO_THREAD_run_once()
    109.   }
    110.   
    111. > int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
    112.   {
    113.       if (pthread_once(once, init) != 0)

crypto/threads_pthread.c:113:9: Taking true branch
    111.   int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
    112.   {
    113.       if (pthread_once(once, init) != 0)
                   ^
    114.           return 0;
    115.   

crypto/threads_pthread.c:114:9: 
    112.   {
    113.       if (pthread_once(once, init) != 0)
    114. >         return 0;
    115.   
    116.       return 1;

crypto/threads_pthread.c:117:1: return from a call to CRYPTO_THREAD_run_once
    115.   
    116.       return 1;
    117. > }
    118.   
    119.   int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))

crypto/ex_data.c:59:10: Condition is false
  57.       }
  58.   
  59.       if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
                 ^
  60.           CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
  61.           return NULL;

crypto/ex_data.c:59:10: Taking false branch
  57.       }
  58.   
  59.       if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
                 ^
  60.           CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
  61.           return NULL;

crypto/ex_data.c:64:9: Taking false branch
  62.       }
  63.   
  64.       if (ex_data_lock == NULL) {
                ^
  65.           /*
  66.            * This can happen in normal operation when using CRYPTO_mem_leaks().

crypto/ex_data.c:77:5: 
  75.       }
  76.   
  77. >     ip = &ex_data[class_index];
  78.       CRYPTO_THREAD_write_lock(ex_data_lock);
  79.       return ip;

crypto/ex_data.c:78:5: 
  76.   
  77.       ip = &ex_data[class_index];
  78. >     CRYPTO_THREAD_write_lock(ex_data_lock);
  79.       return ip;
  80.   }

crypto/threads_pthread.c:70:1: start of procedure CRYPTO_THREAD_write_lock()
    68.   }
    69.   
    70. > int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
    71.   {
    72.   # ifdef USE_RWLOCK

crypto/threads_pthread.c:73:9: Taking true branch
    71.   {
    72.   # ifdef USE_RWLOCK
    73.       if (pthread_rwlock_wrlock(lock) != 0)
                  ^
    74.           return 0;
    75.   # else

crypto/threads_pthread.c:74:9: 
    72.   # ifdef USE_RWLOCK
    73.       if (pthread_rwlock_wrlock(lock) != 0)
    74. >         return 0;
    75.   # else
    76.       if (pthread_mutex_lock(lock) != 0)

crypto/threads_pthread.c:81:1: return from a call to CRYPTO_THREAD_write_lock
    79.   
    80.       return 1;
    81. > }
    82.   
    83.   int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)

crypto/ex_data.c:79:5: 
  77.       ip = &ex_data[class_index];
  78.       CRYPTO_THREAD_write_lock(ex_data_lock);
  79. >     return ip;
  80.   }
  81.   

crypto/ex_data.c:80:1: return from a call to get_and_lock
  78.       CRYPTO_THREAD_write_lock(ex_data_lock);
  79.       return ip;
  80. > }
  81.   
  82.   static void cleanup_cb(EX_CALLBACK *funcs)

crypto/ex_data.c:383:5: 
381.   
382.       ip = get_and_lock(class_index);
383. >     f = sk_EX_CALLBACK_value(ip->meth, idx);
384.       CRYPTO_THREAD_unlock(ex_data_lock);
385.   

include/internal/cryptlib.h:47:1: start of procedure sk_EX_CALLBACK_value()
  45.   typedef struct ex_callback_st EX_CALLBACK;
  46.   
  47. > DEFINE_STACK_OF(EX_CALLBACK)
  48.   
  49.   typedef struct app_mem_info_st APP_INFO;

crypto/stack/stack.c:385:1: start of procedure OPENSSL_sk_value()
    383.   }
    384.   
    385. > void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
    386.   {
    387.       if (st == NULL || i < 0 || i >= st->num)

crypto/stack/stack.c:387:9: Taking false branch
    385.   void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
    386.   {
    387.       if (st == NULL || i < 0 || i >= st->num)
                   ^
    388.           return NULL;
    389.       return (void *)st->data[i];

crypto/stack/stack.c:387:23: Taking true branch
    385.   void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
    386.   {
    387.       if (st == NULL || i < 0 || i >= st->num)
                                 ^
    388.           return NULL;
    389.       return (void *)st->data[i];

crypto/stack/stack.c:388:9: 
    386.   {
    387.       if (st == NULL || i < 0 || i >= st->num)
    388. >         return NULL;
    389.       return (void *)st->data[i];
    390.   }

crypto/stack/stack.c:390:1: return from a call to OPENSSL_sk_value
    388.           return NULL;
    389.       return (void *)st->data[i];
    390. > }
    391.   
    392.   void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data)

include/internal/cryptlib.h:47:1: return from a call to sk_EX_CALLBACK_value
  45.   typedef struct ex_callback_st EX_CALLBACK;
  46.   
  47. > DEFINE_STACK_OF(EX_CALLBACK)
  48.   
  49.   typedef struct app_mem_info_st APP_INFO;

crypto/ex_data.c:384:5: 
382.       ip = get_and_lock(class_index);
383.       f = sk_EX_CALLBACK_value(ip->meth, idx);
384. >     CRYPTO_THREAD_unlock(ex_data_lock);
385.   
386.       /*

crypto/threads_pthread.c:83:1: start of procedure CRYPTO_THREAD_unlock()
  81.   }
  82.   
  83. > int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
  84.   {
  85.   # ifdef USE_RWLOCK

crypto/threads_pthread.c:86:9: Taking true branch
  84.   {
  85.   # ifdef USE_RWLOCK
  86.       if (pthread_rwlock_unlock(lock) != 0)
                ^
  87.           return 0;
  88.   # else

crypto/threads_pthread.c:87:9: 
  85.   # ifdef USE_RWLOCK
  86.       if (pthread_rwlock_unlock(lock) != 0)
  87. >         return 0;
  88.   # else
  89.       if (pthread_mutex_unlock(lock) != 0)

crypto/threads_pthread.c:94:1: return from a call to CRYPTO_THREAD_unlock
  92.   
  93.       return 1;
  94. > }
  95.   
  96.   void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)

crypto/ex_data.c:390:5: 
388.        * everything necessary to support placing the new data in the right spot.
389.        */
390. >     f->new_func(obj, curval, ad, idx, f->argl, f->argp);
391.   
392.       return 1;
