crypto/ex_data.c:392: error: NULL_DEREFERENCE
  pointer `f` last assigned on line 385 could be null and is dereferenced at line 392, column 9.
Showing all 42 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:429:1: start of procedure CRYPTO_get_ex_data()
  427.    * particular index in the class used by this variable
  428.    */
  429. > void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
  430.   {
  431.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))

crypto/ex_data.c:431:9: Taking true branch
  429.   void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
  430.   {
  431.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))
                 ^
  432.           return NULL;
  433.       return sk_void_value(ad->sk, idx);

crypto/ex_data.c:432:9: 
  430.   {
  431.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))
  432. >         return NULL;
  433.       return sk_void_value(ad->sk, idx);
  434.   }

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

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.       if (ip == NULL)
384.           return 0;

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:9: Taking false branch
381.   
382.       ip = get_and_lock(class_index);
383.       if (ip == NULL)
               ^
384.           return 0;
385.       f = sk_EX_CALLBACK_value(ip->meth, idx);

crypto/ex_data.c:385:5: 
383.       if (ip == NULL)
384.           return 0;
385. >     f = sk_EX_CALLBACK_value(ip->meth, idx);
386.       CRYPTO_THREAD_unlock(ex_data_lock);
387.   

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:386:5: 
384.           return 0;
385.       f = sk_EX_CALLBACK_value(ip->meth, idx);
386. >     CRYPTO_THREAD_unlock(ex_data_lock);
387.   
388.       /*

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:392:9: 
390.        * everything necessary to support placing the new data in the right spot.
391.        */
392. >     if (f->new_func == NULL)
393.           return 0;
394.   

int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
                         int idx)
{
    EX_CALLBACK *f;
    EX_CALLBACKS *ip;
    void *curval;
    curval = CRYPTO_get_ex_data(ad, idx);
    if (curval != NULL)
        return 1;
    ip = get_and_lock(class_index);
    if (ip == NULL)
        return 0;
    f = sk_EX_CALLBACK_value(ip->meth, idx);
    CRYPTO_THREAD_unlock(ex_data_lock);
    if (f->new_func == NULL)
        return 0;
    f->new_func(obj, curval, ad, idx, f->argl, f->argp);
    return 1;
}
['int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,\n                         int idx)\n{\n    EX_CALLBACK *f;\n    EX_CALLBACKS *ip;\n    void *curval;\n    curval = CRYPTO_get_ex_data(ad, idx);\n    if (curval != NULL)\n        return 1;\n    ip = get_and_lock(class_index);\n    if (ip == NULL)\n        return 0;\n    f = sk_EX_CALLBACK_value(ip->meth, idx);\n    CRYPTO_THREAD_unlock(ex_data_lock);\n    if (f->new_func == NULL)\n        return 0;\n    f->new_func(obj, curval, ad, idx, f->argl, f->argp);\n    return 1;\n}', 'void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)\n{\n    if (ad->sk == NULL || idx >= sk_void_num(ad->sk))\n        return NULL;\n    return sk_void_value(ad->sk, idx);\n}', 'static EX_CALLBACKS *get_and_lock(int class_index)\n{\n    EX_CALLBACKS *ip;\n    if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {\n        CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);\n        return NULL;\n    }\n    if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {\n        CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);\n        return NULL;\n    }\n    if (ex_data_lock == NULL) {\n         return NULL;\n    }\n    ip = &ex_data[class_index];\n    CRYPTO_THREAD_write_lock(ex_data_lock);\n    return ip;\n}', 'int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))\n{\n    if (pthread_once(once, init) != 0)\n        return 0;\n    return 1;\n}', 'int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)\n{\n# ifdef USE_RWLOCK\n    if (pthread_rwlock_wrlock(lock) != 0)\n        return 0;\n# else\n    if (pthread_mutex_lock(lock) != 0)\n        return 0;\n# endif\n    return 1;\n}', 'DEFINE_STACK_OF(EX_CALLBACK)', 'void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)\n{\n    if (st == NULL || i < 0 || i >= st->num)\n        return NULL;\n    return (void *)st->data[i];\n}', 'int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)\n{\n# ifdef USE_RWLOCK\n    if (pthread_rwlock_unlock(lock) != 0)\n        return 0;\n# else\n    if (pthread_mutex_unlock(lock) != 0)\n        return 0;\n# endif\n    return 1;\n}']