crypto/lock.c:491: error: USE_AFTER_FREE
  call to `CRYPTO_lock()` eventually accesses memory that was invalidated by call to `free()` on line 477 indirectly during the call to `CRYPTO_lock()`.
Showing all 22 steps of the trace


crypto/lock.c:477:9: invalidation part of the trace starts here
475.   #endif
476.       } else {
477.           CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
               ^
478.   
479.           ret = *pointer + amount;

crypto/lock.c:477:9: global variable `dyn_locks` accessed here
  475.   #endif
  476.       } else {
  477.           CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
                 ^
  478.   
  479.           ret = *pointer + amount;

crypto/lock.c:477:9: when calling `CRYPTO_lock` here
  475.   #endif
  476.       } else {
  477.           CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
                 ^
  478.   
  479.           ret = *pointer + amount;

crypto/lock.c:444:19: global variable `dyn_locks` accessed here
    442.           if (dynlock_lock_callback != NULL) {
    443.               struct CRYPTO_dynlock_value *pointer
    444.                   = CRYPTO_get_dynlock_value(type);
                             ^
    445.   
    446.               OPENSSL_assert(pointer != NULL);

crypto/lock.c:450:13: when calling `CRYPTO_destroy_dynlockid` here
    448.               dynlock_lock_callback(mode, pointer, file, line);
    449.   
    450.               CRYPTO_destroy_dynlockid(type);
                       ^
    451.           }
    452.       } else if (locking_callback != NULL)

crypto/lock.c:301:9: global variable `dyn_locks` accessed here
      299.       CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
      300.   
      301.       if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {
                     ^
      302.           CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
      303.           return;

crypto/lock.c:305:15: passed as argument to `sk_CRYPTO_dynlock_value`
      303.           return;
      304.       }
      305.       pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
                           ^
      306.       if (pointer != NULL) {
      307.           --pointer->references;

crypto/lock.c:305:15: return from call to `sk_CRYPTO_dynlock_value`
      303.           return;
      304.       }
      305.       pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
                           ^
      306.       if (pointer != NULL) {
      307.           --pointer->references;

crypto/lock.c:305:5: assigned
      303.           return;
      304.       }
      305.       pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
                 ^
      306.       if (pointer != NULL) {
      307.           --pointer->references;

crypto/lock.c:323:9: when calling `CRYPTO_free` here
      321.       if (pointer) {
      322.           dynlock_destroy_callback(pointer->data, OPENSSL_FILE, OPENSSL_LINE);
      323.           OPENSSL_free(pointer);
                     ^
      324.       }
      325.   }

crypto/mem.c:225:1: parameter `str` of CRYPTO_free
        223.   }
        224.   
        225. > void CRYPTO_free(void *str, const char *file, int line)
        226.   {
        227.       if (free_impl != NULL && free_impl != &CRYPTO_free) {

crypto/mem.c:241:5: was invalidated by call to `free()`
        239.       }
        240.   #else
        241.       free(str);
                   ^
        242.   #endif
        243.   }

crypto/lock.c:477:9: use-after-lifetime part of the trace starts here
475.   #endif
476.       } else {
477.           CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
               ^
478.   
479.           ret = *pointer + amount;

crypto/lock.c:477:9: global variable `dyn_locks` accessed here
  475.   #endif
  476.       } else {
  477.           CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);
                 ^
  478.   
  479.           ret = *pointer + amount;

crypto/lock.c:491:9: when calling `CRYPTO_lock` here
  489.   #endif
  490.           *pointer = ret;
  491.           CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line);
                 ^
  492.       }
  493.       return (ret);

crypto/lock.c:444:19: global variable `dyn_locks` accessed here
    442.           if (dynlock_lock_callback != NULL) {
    443.               struct CRYPTO_dynlock_value *pointer
    444.                   = CRYPTO_get_dynlock_value(type);
                             ^
    445.   
    446.               OPENSSL_assert(pointer != NULL);

crypto/lock.c:444:19: when calling `CRYPTO_get_dynlock_value` here
    442.           if (dynlock_lock_callback != NULL) {
    443.               struct CRYPTO_dynlock_value *pointer
    444.                   = CRYPTO_get_dynlock_value(type);
                             ^
    445.   
    446.               OPENSSL_assert(pointer != NULL);

crypto/lock.c:335:9: global variable `dyn_locks` accessed here
      333.       CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
      334.   
      335.       if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
                     ^
      336.           pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
      337.       if (pointer)

crypto/lock.c:336:19: passed as argument to `sk_CRYPTO_dynlock_value`
      334.   
      335.       if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
      336.           pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
                               ^
      337.       if (pointer)
      338.           pointer->references++;

crypto/lock.c:336:19: return from call to `sk_CRYPTO_dynlock_value`
      334.   
      335.       if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
      336.           pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
                               ^
      337.       if (pointer)
      338.           pointer->references++;

crypto/lock.c:336:9: assigned
      334.   
      335.       if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
      336.           pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
                     ^
      337.       if (pointer)
      338.           pointer->references++;

crypto/lock.c:343:16: invalid access occurs here
      341.   
      342.       if (pointer)
      343.           return pointer->data;
                            ^
      344.       return NULL;
      345.   }

struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
{
    CRYPTO_dynlock *pointer = NULL;
    if (i)
        i = -i - 1;
    CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
    if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
        pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
    if (pointer)
        pointer->references++;
    CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
    if (pointer)
        return pointer->data;
    return NULL;
}
['int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,\n                    int line)\n{\n    int ret = 0;\n    if (add_lock_callback != NULL) {\n#ifdef LOCK_DEBUG\n        int before = *pointer;\n#endif\n        ret = add_lock_callback(pointer, amount, type, file, line);\n#ifdef LOCK_DEBUG\n        {\n            CRYPTO_THREADID id;\n            CRYPTO_THREADID_current(&id);\n            fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\\n",\n                    CRYPTO_THREADID_hash(&id), before, amount, ret,\n                    CRYPTO_get_lock_name(type), file, line);\n        }\n#endif\n    } else {\n        CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line);\n        ret = *pointer + amount;\n#ifdef LOCK_DEBUG\n        {\n            CRYPTO_THREADID id;\n            CRYPTO_THREADID_current(&id);\n            fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\\n",\n                    CRYPTO_THREADID_hash(&id),\n                    *pointer, amount, ret,\n                    CRYPTO_get_lock_name(type), file, line);\n        }\n#endif\n        *pointer = ret;\n        CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line);\n    }\n    return (ret);\n}', 'void CRYPTO_lock(int mode, int type, const char *file, int line)\n{\n#ifdef LOCK_DEBUG\n    {\n        CRYPTO_THREADID id;\n        char *rw_text, *operation_text;\n        if (mode & CRYPTO_LOCK)\n            operation_text = "lock  ";\n        else if (mode & CRYPTO_UNLOCK)\n            operation_text = "unlock";\n        else\n            operation_text = "ERROR ";\n        if (mode & CRYPTO_READ)\n            rw_text = "r";\n        else if (mode & CRYPTO_WRITE)\n            rw_text = "w";\n        else\n            rw_text = "ERROR";\n        CRYPTO_THREADID_current(&id);\n        fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\\n",\n                CRYPTO_THREADID_hash(&id), rw_text, operation_text,\n                CRYPTO_get_lock_name(type), file, line);\n    }\n#endif\n    if (type < 0) {\n        if (dynlock_lock_callback != NULL) {\n            struct CRYPTO_dynlock_value *pointer\n                = CRYPTO_get_dynlock_value(type);\n            OPENSSL_assert(pointer != NULL);\n            dynlock_lock_callback(mode, pointer, file, line);\n            CRYPTO_destroy_dynlockid(type);\n        }\n    } else if (locking_callback != NULL)\n        locking_callback(mode, type, file, line);\n}', 'void CRYPTO_destroy_dynlockid(int i)\n{\n    CRYPTO_dynlock *pointer = NULL;\n    if (i)\n        i = -i - 1;\n    if (dynlock_destroy_callback == NULL)\n        return;\n    CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);\n    if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {\n        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);\n        return;\n    }\n    pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);\n    if (pointer != NULL) {\n        --pointer->references;\n#ifdef REF_DEBUG\n        if (pointer->references < 0) {\n            OPENSSL_showfatal("CRYPTO_destroy_dynlockid, bad reference count\\n");\n            abort();\n        } else\n#endif\n        if (pointer->references <= 0) {\n            (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);\n        } else\n            pointer = NULL;\n    }\n    CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);\n    if (pointer) {\n        dynlock_destroy_callback(pointer->data, OPENSSL_FILE, OPENSSL_LINE);\n        OPENSSL_free(pointer);\n    }\n}', 'void CRYPTO_free(void *str, const char *file, int line)\n{\n    if (free_impl != NULL && free_impl != &CRYPTO_free) {\n        free_impl(str, file, line);\n        return;\n    }\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_free(str, 0, file, line);\n        free(str);\n        CRYPTO_mem_debug_free(str, 1, file, line);\n    } else {\n        free(str);\n    }\n#else\n    free(str);\n#endif\n}', 'struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)\n{\n    CRYPTO_dynlock *pointer = NULL;\n    if (i)\n        i = -i - 1;\n    CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);\n    if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))\n        pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);\n    if (pointer)\n        pointer->references++;\n    CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);\n    if (pointer)\n        return pointer->data;\n    return NULL;\n}']