apps/engine.c:314: error: USE_AFTER_FREE
  call to `sk_OPENSSL_CSTRING_push()` eventually accesses memory that was invalidated by call to `free()` on line 314 indirectly during the call to `sk_OPENSSL_CSTRING_push()`.
Showing all 24 steps of the trace


apps/engine.c:297:42: invalidation part of the trace starts here
295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
296.       ENGINE *e;
297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
                                                ^
298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:297:42: passed as argument to `sk_OPENSSL_CSTRING_new_null`
  295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
  296.       ENGINE *e;
  297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
                                                  ^
  298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
  299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:297:42: return from call to `sk_OPENSSL_CSTRING_new_null`
  295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
  296.       ENGINE *e;
  297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
                                                  ^
  298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
  299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:297:5: assigned
  295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
  296.       ENGINE *e;
  297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
             ^
  298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
  299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:314:9: when calling `sk_OPENSSL_CSTRING_push` here
  312.       prog = argv[0];
  313.       while ((argv1 = argv[1]) != NULL && *argv1 != '-') {
  314.           sk_OPENSSL_CSTRING_push(engines, argv1);
                 ^
  315.           argc--;
  316.           argv++;

include/openssl/safestack.h:160:1: parameter `sk` of sk_OPENSSL_CSTRING_push
    158.    */
    159.   DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
    160. > DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char)
    161.   
    162.   /*

include/openssl/safestack.h:160:1: when calling `OPENSSL_sk_push` here
    158.    */
    159.   DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
    160. > DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char)
    161.   
    162.   /*

crypto/stack/stack.c:321:1: parameter `st` of OPENSSL_sk_push
      319.   }
      320.   
      321. > int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
      322.   {
      323.       if (st == NULL)

crypto/stack/stack.c:325:12: when calling `OPENSSL_sk_insert` here
      323.       if (st == NULL)
      324.           return -1;
      325.       return OPENSSL_sk_insert(st, data, st->num);
                        ^
      326.   }
      327.   

crypto/stack/stack.c:232:1: parameter `st` of OPENSSL_sk_insert
        230.   }
        231.   
        232. > int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)
        233.   {
        234.       if (st == NULL || st->num == max_nodes)

crypto/stack/stack.c:237:10: when calling `sk_reserve` here
        235.           return 0;
        236.   
        237.       if (!sk_reserve(st, 1, 0))
                        ^
        238.           return 0;
        239.   

crypto/stack/stack.c:156:1: parameter `st` of sk_reserve
          154.   
          155.   /* internal STACK storage allocation */
          156. > static int sk_reserve(OPENSSL_STACK *st, int n, int exact)
          157.   {
          158.       const void **tmpdata;

crypto/stack/stack.c:193:15: when calling `CRYPTO_realloc` here
          191.       }
          192.   
          193.       tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc);
                               ^
          194.       if (tmpdata == NULL)
          195.           return 0;

crypto/mem.c:231:1: parameter `str` of CRYPTO_realloc
            229.   }
            230.   
            231. > void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
            232.   {
            233.       INCREMENT(realloc_count);

crypto/mem.c:242:9: when calling `CRYPTO_free` here
            240.   
            241.       if (num == 0) {
            242.           CRYPTO_free(str, file, line);
                           ^
            243.           return NULL;
            244.       }

crypto/mem.c:289:1: parameter `str` of CRYPTO_free
              287.   }
              288.   
              289. > void CRYPTO_free(void *str, const char *file, int line)
              290.   {
              291.       INCREMENT(free_count);

crypto/mem.c:306:5: was invalidated by call to `free()`
              304.       }
              305.   #else
              306.       free(str);
                         ^
              307.   #endif
              308.   }

apps/engine.c:297:42: use-after-lifetime part of the trace starts here
295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
296.       ENGINE *e;
297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
                                                ^
298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:297:42: passed as argument to `sk_OPENSSL_CSTRING_new_null`
  295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
  296.       ENGINE *e;
  297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
                                                  ^
  298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
  299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:297:42: return from call to `sk_OPENSSL_CSTRING_new_null`
  295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
  296.       ENGINE *e;
  297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
                                                  ^
  298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
  299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:297:5: assigned
  295.       int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
  296.       ENGINE *e;
  297.       STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
             ^
  298.       STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
  299.       STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();

apps/engine.c:314:9: when calling `sk_OPENSSL_CSTRING_push` here
  312.       prog = argv[0];
  313.       while ((argv1 = argv[1]) != NULL && *argv1 != '-') {
  314.           sk_OPENSSL_CSTRING_push(engines, argv1);
                 ^
  315.           argc--;
  316.           argv++;

crypto/mem.c:289:1: parameter `str` of CRYPTO_free
    287.   }
    288.   
    289. > void CRYPTO_free(void *str, const char *file, int line)
    290.   {
    291.       INCREMENT(free_count);

crypto/mem.c:306:5: invalid access occurs here
    304.       }
    305.   #else
    306.       free(str);
               ^
    307.   #endif
    308.   }

void CRYPTO_free(void *str, const char *file, int line)
{
    INCREMENT(free_count);
    if (free_impl != NULL && free_impl != &CRYPTO_free) {
        free_impl(str, file, line);
        return;
    }
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    if (call_malloc_debug) {
        CRYPTO_mem_debug_free(str, 0, file, line);
        free(str);
        CRYPTO_mem_debug_free(str, 1, file, line);
    } else {
        free(str);
    }
#else
    free(str);
#endif
}
['int engine_main(int argc, char **argv)\n{\n    int ret = 1, i;\n    int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;\n    ENGINE *e;\n    STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();\n    STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();\n    STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();\n    BIO *out;\n    const char *indent = "     ";\n    OPTION_CHOICE o;\n    char *prog;\n    char *argv1;\n    out = dup_bio_out(FORMAT_TEXT);\n    if (engines == NULL || pre_cmds == NULL || post_cmds == NULL)\n        goto end;\n    prog = argv[0];\n    while ((argv1 = argv[1]) != NULL && *argv1 != \'-\') {\n        sk_OPENSSL_CSTRING_push(engines, argv1);\n        argc--;\n        argv++;\n    }\n    argv[0] = prog;\n    opt_init(argc, argv, engine_options);\n    while ((o = opt_next()) != OPT_EOF) {\n        switch (o) {\n        case OPT_EOF:\n        case OPT_ERR:\n            BIO_printf(bio_err, "%s: Use -help for summary.\\n", prog);\n            goto end;\n        case OPT_HELP:\n            opt_help(engine_options);\n            ret = 0;\n            goto end;\n        case OPT_VVVV:\n        case OPT_VVV:\n        case OPT_VV:\n        case OPT_V:\n            i = (int)(o - OPT_V) + 1;\n            if (verbose < i)\n                verbose = i;\n            break;\n        case OPT_C:\n            list_cap = 1;\n            break;\n        case OPT_TT:\n            test_avail_noise++;\n        case OPT_T:\n            test_avail++;\n            break;\n        case OPT_PRE:\n            sk_OPENSSL_STRING_push(pre_cmds, opt_arg());\n            break;\n        case OPT_POST:\n            sk_OPENSSL_STRING_push(post_cmds, opt_arg());\n            break;\n        }\n    }\n    argc = opt_num_rest();\n    argv = opt_rest();\n    for ( ; *argv; argv++) {\n        if (**argv == \'-\') {\n            BIO_printf(bio_err, "%s: Cannot mix flags and engine names.\\n",\n                       prog);\n            BIO_printf(bio_err, "%s: Use -help for summary.\\n", prog);\n            goto end;\n        }\n        sk_OPENSSL_CSTRING_push(engines, *argv);\n    }\n    if (sk_OPENSSL_CSTRING_num(engines) == 0) {\n        for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {\n            sk_OPENSSL_CSTRING_push(engines, ENGINE_get_id(e));\n        }\n    }\n    ret = 0;\n    for (i = 0; i < sk_OPENSSL_CSTRING_num(engines); i++) {\n        const char *id = sk_OPENSSL_CSTRING_value(engines, i);\n        if ((e = ENGINE_by_id(id)) != NULL) {\n            const char *name = ENGINE_get_name(e);\n            BIO_printf(out, "(%s) %s\\n", id, name);\n            util_do_cmds(e, pre_cmds, out, indent);\n            if (strcmp(ENGINE_get_id(e), id) != 0) {\n                BIO_printf(out, "Loaded: (%s) %s\\n",\n                           ENGINE_get_id(e), ENGINE_get_name(e));\n            }\n            if (list_cap) {\n                int cap_size = 256;\n                char *cap_buf = NULL;\n                int k, n;\n                const int *nids;\n                ENGINE_CIPHERS_PTR fn_c;\n                ENGINE_DIGESTS_PTR fn_d;\n                ENGINE_PKEY_METHS_PTR fn_pk;\n                if (ENGINE_get_RSA(e) != NULL\n                    && !append_buf(&cap_buf, &cap_size, "RSA"))\n                    goto end;\n                if (ENGINE_get_DSA(e) != NULL\n                    && !append_buf(&cap_buf, &cap_size, "DSA"))\n                    goto end;\n                if (ENGINE_get_DH(e) != NULL\n                    && !append_buf(&cap_buf, &cap_size, "DH"))\n                    goto end;\n                if (ENGINE_get_RAND(e) != NULL\n                    && !append_buf(&cap_buf, &cap_size, "RAND"))\n                    goto end;\n                fn_c = ENGINE_get_ciphers(e);\n                if (fn_c == NULL)\n                    goto skip_ciphers;\n                n = fn_c(e, NULL, &nids, 0);\n                for (k = 0; k < n; ++k)\n                    if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))\n                        goto end;\n skip_ciphers:\n                fn_d = ENGINE_get_digests(e);\n                if (fn_d == NULL)\n                    goto skip_digests;\n                n = fn_d(e, NULL, &nids, 0);\n                for (k = 0; k < n; ++k)\n                    if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))\n                        goto end;\n skip_digests:\n                fn_pk = ENGINE_get_pkey_meths(e);\n                if (fn_pk == NULL)\n                    goto skip_pmeths;\n                n = fn_pk(e, NULL, &nids, 0);\n                for (k = 0; k < n; ++k)\n                    if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))\n                        goto end;\n skip_pmeths:\n                {\n                    struct util_store_cap_data store_ctx;\n                    store_ctx.engine = e;\n                    store_ctx.cap_buf = &cap_buf;\n                    store_ctx.cap_size = &cap_size;\n                    store_ctx.ok = 1;\n                    OSSL_STORE_do_all_loaders(util_store_cap, &store_ctx);\n                    if (!store_ctx.ok)\n                        goto end;\n                }\n                if (cap_buf != NULL && (*cap_buf != \'\\0\'))\n                    BIO_printf(out, " [%s]\\n", cap_buf);\n                OPENSSL_free(cap_buf);\n            }\n            if (test_avail) {\n                BIO_printf(out, "%s", indent);\n                if (ENGINE_init(e)) {\n                    BIO_printf(out, "[ available ]\\n");\n                    util_do_cmds(e, post_cmds, out, indent);\n                    ENGINE_finish(e);\n                } else {\n                    BIO_printf(out, "[ unavailable ]\\n");\n                    if (test_avail_noise)\n                        ERR_print_errors_fp(stdout);\n                    ERR_clear_error();\n                }\n            }\n            if ((verbose > 0) && !util_verbose(e, verbose, out, indent))\n                goto end;\n            ENGINE_free(e);\n        } else {\n            ERR_print_errors(bio_err);\n            if (++ret > 127)\n                ret = 127;\n        }\n    }\n end:\n    ERR_print_errors(bio_err);\n    sk_OPENSSL_CSTRING_free(engines);\n    sk_OPENSSL_STRING_free(pre_cmds);\n    sk_OPENSSL_STRING_free(post_cmds);\n    BIO_free_all(out);\n    return ret;\n}', 'DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char)', 'int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)\n{\n    if (st == NULL)\n        return -1;\n    return OPENSSL_sk_insert(st, data, st->num);\n}', 'int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)\n{\n    if (st == NULL || st->num == max_nodes)\n        return 0;\n    if (!sk_reserve(st, 1, 0))\n        return 0;\n    if ((loc >= st->num) || (loc < 0)) {\n        st->data[st->num] = data;\n    } else {\n        memmove(&st->data[loc + 1], &st->data[loc],\n                sizeof(st->data[0]) * (st->num - loc));\n        st->data[loc] = data;\n    }\n    st->num++;\n    st->sorted = 0;\n    return st->num;\n}', 'static int sk_reserve(OPENSSL_STACK *st, int n, int exact)\n{\n    const void **tmpdata;\n    int num_alloc;\n    if (n > max_nodes - st->num)\n        return 0;\n    num_alloc = st->num + n;\n    if (num_alloc < min_nodes)\n        num_alloc = min_nodes;\n    if (st->data == NULL) {\n        st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc);\n        if (st->data == NULL)\n            return 0;\n        st->num_alloc = num_alloc;\n        return 1;\n    }\n    if (!exact) {\n        if (num_alloc <= st->num_alloc)\n            return 1;\n        num_alloc = compute_growth(num_alloc, st->num_alloc);\n        if (num_alloc == 0)\n            return 0;\n    } else if (num_alloc == st->num_alloc) {\n        return 1;\n    }\n    tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc);\n    if (tmpdata == NULL)\n        return 0;\n    st->data = tmpdata;\n    st->num_alloc = num_alloc;\n    return 1;\n}', 'void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)\n{\n    INCREMENT(realloc_count);\n    if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc)\n        return realloc_impl(str, num, file, line);\n    FAILTEST();\n    if (str == NULL)\n        return CRYPTO_malloc(num, file, line);\n    if (num == 0) {\n        CRYPTO_free(str, file, line);\n        return NULL;\n    }\n    allow_customize = 0;\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        void *ret;\n        CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line);\n        ret = realloc(str, num);\n        CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line);\n        return ret;\n    }\n#else\n    (void)(file); (void)(line);\n#endif\n    return realloc(str, num);\n}', 'void CRYPTO_free(void *str, const char *file, int line)\n{\n    INCREMENT(free_count);\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}']