test/exdatatest.c:251: error: USE_AFTER_FREE
  call to `MYOBJ_gethello()` eventually accesses memory that was invalidated by call to `free()` on line 250 indirectly during the call to `MYOBJ_sethello()`.
Showing all 30 steps of the trace


test/exdatatest.c:233:5: invalidation part of the trace starts here
231.                                            saved_argl, saved_argp,
232.                                            exnew2, exdup2, exfree2);
233.       t1 = MYOBJ_new();
           ^
234.       t2 = MYOBJ_new();
235.       if (!TEST_int_eq(t1->st, 1) || !TEST_int_eq(t2->st, 1))

test/exdatatest.c:233:5: assigned
  231.                                            saved_argl, saved_argp,
  232.                                            exnew2, exdup2, exfree2);
  233.       t1 = MYOBJ_new();
             ^
  234.       t2 = MYOBJ_new();
  235.       if (!TEST_int_eq(t1->st, 1) || !TEST_int_eq(t2->st, 1))

test/exdatatest.c:250:5: when calling `MYOBJ_sethello` here
  248.           return 0;
  249.   
  250.       MYOBJ_sethello(t1, p);
             ^
  251.       cp = MYOBJ_gethello(t1);
  252.       if (!TEST_ptr_eq(cp, p))

test/exdatatest.c:143:1: parameter `obj` of MYOBJ_sethello
    141.   }
    142.   
    143. > static void MYOBJ_sethello(MYOBJ *obj, char *cp)
    144.   {
    145.       obj->st = CRYPTO_set_ex_data(&obj->ex_data, saved_idx, cp);

test/exdatatest.c:145:15: when calling `CRYPTO_set_ex_data` here
    143.   static void MYOBJ_sethello(MYOBJ *obj, char *cp)
    144.   {
    145.       obj->st = CRYPTO_set_ex_data(&obj->ex_data, saved_idx, cp);
                         ^
    146.       if (!TEST_int_eq(obj->st, 1))
    147.           gbl_result = 0;

crypto/ex_data.c:433:1: parameter `ad` of CRYPTO_set_ex_data
      431.    * particular index in the class used by this variable
      432.    */
      433. > int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
      434.   {
      435.       int i;

crypto/ex_data.c:445:14: when calling `sk_void_push` here
      443.   
      444.       for (i = sk_void_num(ad->sk); i <= idx; ++i) {
      445.           if (!sk_void_push(ad->sk, NULL)) {
                          ^
      446.               CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
      447.               return 0;

include/openssl/crypto.h:90:1: parameter `sk` of sk_void_push
        88.       STACK_OF(void) *sk;
        89.   };
        90. > DEFINE_STACK_OF(void)
        91.   
        92.   /*

include/openssl/crypto.h:90:1: when calling `OPENSSL_sk_push` here
        88.       STACK_OF(void) *sk;
        89.   };
        90. > DEFINE_STACK_OF(void)
        91.   
        92.   /*

crypto/stack/stack.c:325:1: parameter `st` of OPENSSL_sk_push
          323.   }
          324.   
          325. > int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
          326.   {
          327.       if (st == NULL)

crypto/stack/stack.c:329:12: when calling `OPENSSL_sk_insert` here
          327.       if (st == NULL)
          328.           return -1;
          329.       return OPENSSL_sk_insert(st, data, st->num);
                            ^
          330.   }
          331.   

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

crypto/stack/stack.c:241:10: when calling `sk_reserve` here
            239.           return 0;
            240.   
            241.       if (!sk_reserve(st, 1, 0))
                            ^
            242.           return 0;
            243.   

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

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

crypto/mem.c:238:1: parameter `str` of CRYPTO_realloc
                236.   }
                237.   
                238. > void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
                239.   {
                240.       INCREMENT(realloc_count);

crypto/mem.c:249:9: when calling `CRYPTO_free` here
                247.   
                248.       if (num == 0) {
                249.           CRYPTO_free(str, file, line);
                               ^
                250.           return NULL;
                251.       }

crypto/mem.c:295:1: parameter `str` of CRYPTO_free
                  293.   }
                  294.   
                  295. > void CRYPTO_free(void *str, const char *file, int line)
                  296.   {
                  297.       INCREMENT(free_count);

crypto/mem.c:312:5: was invalidated by call to `free()`
                  310.       }
                  311.   #else
                  312.       free(str);
                             ^
                  313.   #endif
                  314.   }

test/exdatatest.c:233:5: use-after-lifetime part of the trace starts here
231.                                            saved_argl, saved_argp,
232.                                            exnew2, exdup2, exfree2);
233.       t1 = MYOBJ_new();
           ^
234.       t2 = MYOBJ_new();
235.       if (!TEST_int_eq(t1->st, 1) || !TEST_int_eq(t2->st, 1))

test/exdatatest.c:233:5: assigned
  231.                                            saved_argl, saved_argp,
  232.                                            exnew2, exdup2, exfree2);
  233.       t1 = MYOBJ_new();
             ^
  234.       t2 = MYOBJ_new();
  235.       if (!TEST_int_eq(t1->st, 1) || !TEST_int_eq(t2->st, 1))

test/exdatatest.c:251:10: when calling `MYOBJ_gethello` here
  249.   
  250.       MYOBJ_sethello(t1, p);
  251.       cp = MYOBJ_gethello(t1);
                  ^
  252.       if (!TEST_ptr_eq(cp, p))
  253.           return 0;

test/exdatatest.c:150:1: parameter `obj` of MYOBJ_gethello
    148.   }
    149.   
    150. > static char *MYOBJ_gethello(MYOBJ *obj)
    151.   {
    152.       return CRYPTO_get_ex_data(&obj->ex_data, saved_idx);

test/exdatatest.c:152:12: when calling `CRYPTO_get_ex_data` here
    150.   static char *MYOBJ_gethello(MYOBJ *obj)
    151.   {
    152.       return CRYPTO_get_ex_data(&obj->ex_data, saved_idx);
                      ^
    153.   }
    154.   

crypto/ex_data.c:458:1: parameter `ad` of CRYPTO_get_ex_data
      456.    * particular index in the class used by this variable
      457.    */
      458. > void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
      459.   {
      460.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))

crypto/ex_data.c:462:12: when calling `sk_void_value` here
      460.       if (ad->sk == NULL || idx >= sk_void_num(ad->sk))
      461.           return NULL;
      462.       return sk_void_value(ad->sk, idx);
                        ^
      463.   }
      464.   

include/openssl/crypto.h:90:1: parameter `sk` of sk_void_value
        88.       STACK_OF(void) *sk;
        89.   };
        90. > DEFINE_STACK_OF(void)
        91.   
        92.   /*

include/openssl/crypto.h:90:1: when calling `OPENSSL_sk_value` here
        88.       STACK_OF(void) *sk;
        89.   };
        90. > DEFINE_STACK_OF(void)
        91.   
        92.   /*

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

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

void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
{
    if (st == NULL || i < 0 || i >= st->num)
        return NULL;
    return (void *)st->data[i];
}
['static int test_exdata(void)\n{\n    MYOBJ *t1, *t2, *t3;\n    MYOBJ_EX_DATA *ex_data;\n    const char *cp;\n    char *p;\n    gbl_result = 1;\n    p = OPENSSL_strdup("hello world");\n    saved_argl = 21;\n    saved_argp = OPENSSL_malloc(1);\n    saved_idx = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,\n                                        saved_argl, saved_argp,\n                                        exnew, exdup, exfree);\n    saved_idx2 = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,\n                                         saved_argl, saved_argp,\n                                         exnew2, exdup2, exfree2);\n    t1 = MYOBJ_new();\n    t2 = MYOBJ_new();\n    if (!TEST_int_eq(t1->st, 1) || !TEST_int_eq(t2->st, 1))\n        return 0;\n    if (!TEST_ptr(CRYPTO_get_ex_data(&t1->ex_data, saved_idx2)))\n        return 0;\n    saved_idx3 = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_APP,\n                                         saved_argl, saved_argp,\n                                         exnew2, exdup2, exfree2);\n    if (!TEST_ptr_null(CRYPTO_get_ex_data(&t1->ex_data, saved_idx3)))\n        return 0;\n    MYOBJ_sethello(t1, p);\n    cp = MYOBJ_gethello(t1);\n    if (!TEST_ptr_eq(cp, p))\n        return 0;\n    MYOBJ_sethello2(t1, p);\n    cp = MYOBJ_gethello2(t1);\n    if (!TEST_ptr_eq(cp, p))\n        return 0;\n    MYOBJ_allochello3(t1, p);\n    cp = MYOBJ_gethello3(t1);\n    if (!TEST_ptr_eq(cp, p))\n        return 0;\n    cp = MYOBJ_gethello(t2);\n    if (!TEST_ptr_null(cp))\n        return 0;\n    cp = MYOBJ_gethello2(t2);\n    if (!TEST_ptr_null(cp))\n        return 0;\n    t3 = MYOBJ_dup(t1);\n    if (!TEST_int_eq(t3->st, 1))\n        return 0;\n    ex_data = CRYPTO_get_ex_data(&t3->ex_data, saved_idx2);\n    if (!TEST_ptr(ex_data))\n        return 0;\n    if (!TEST_int_eq(ex_data->dup, 1))\n        return 0;\n    cp = MYOBJ_gethello(t3);\n    if (!TEST_ptr_eq(cp, p))\n        return 0;\n    cp = MYOBJ_gethello2(t3);\n    if (!TEST_ptr_eq(cp, p))\n        return 0;\n    cp = MYOBJ_gethello3(t3);\n    if (!TEST_ptr_eq(cp, p))\n        return 0;\n    MYOBJ_free(t1);\n    MYOBJ_free(t2);\n    MYOBJ_free(t3);\n    OPENSSL_free(saved_argp);\n    OPENSSL_free(p);\n    if (gbl_result)\n      return 1;\n    else\n      return 0;\n}', 'static void MYOBJ_sethello(MYOBJ *obj, char *cp)\n{\n    obj->st = CRYPTO_set_ex_data(&obj->ex_data, saved_idx, cp);\n    if (!TEST_int_eq(obj->st, 1))\n        gbl_result = 0;\n}', 'int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)\n{\n    int i;\n    if (ad->sk == NULL) {\n        if ((ad->sk = sk_void_new_null()) == NULL) {\n            CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);\n            return 0;\n        }\n    }\n    for (i = sk_void_num(ad->sk); i <= idx; ++i) {\n        if (!sk_void_push(ad->sk, NULL)) {\n            CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);\n            return 0;\n        }\n    }\n    sk_void_set(ad->sk, idx, val);\n    return 1;\n}', 'DEFINE_STACK_OF(void)', '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        if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL) {\n            CRYPTOerr(CRYPTO_F_SK_RESERVE, ERR_R_MALLOC_FAILURE);\n            return 0;\n        }\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#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE)\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#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE)\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}', 'static char *MYOBJ_gethello(MYOBJ *obj)\n{\n    return CRYPTO_get_ex_data(&obj->ex_data, saved_idx);\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}', '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}']