crypto/asn1/asn_mime.c:580: error: USE_AFTER_FREE
  call to `mime_hdr_find()` eventually accesses memory that was invalidated by call to `free()` on line 576 indirectly during the call to `mime_parse_hdr()`.
Showing all 29 steps of the trace


crypto/asn1/asn_mime.c:576:20: invalidation part of the trace starts here
574.       MIME_HEADER *hdr;
575.   
576.       if ((headers = mime_parse_hdr(in)) == NULL) {
                          ^
577.           ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
578.           return 0;

crypto/asn1/asn_mime.c:576:20: when calling `mime_parse_hdr` here
  574.       MIME_HEADER *hdr;
  575.   
  576.       if ((headers = mime_parse_hdr(in)) == NULL) {
                            ^
  577.           ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
  578.           return 0;

crypto/asn1/asn_mime.c:677:15: passed as argument to `sk_MIME_HEADER_new`
    675.       int len, state, save_state = 0;
    676.   
    677.       headers = sk_MIME_HEADER_new(mime_hdr_cmp);
                         ^
    678.       if (headers == NULL)
    679.           return NULL;

crypto/asn1/asn_mime.c:677:15: return from call to `sk_MIME_HEADER_new`
    675.       int len, state, save_state = 0;
    676.   
    677.       headers = sk_MIME_HEADER_new(mime_hdr_cmp);
                         ^
    678.       if (headers == NULL)
    679.           return NULL;

crypto/asn1/asn_mime.c:677:5: assigned
    675.       int len, state, save_state = 0;
    676.   
    677.       headers = sk_MIME_HEADER_new(mime_hdr_cmp);
               ^
    678.       if (headers == NULL)
    679.           return NULL;

crypto/asn1/asn_mime.c:711:21: when calling `sk_MIME_HEADER_push` here
    709.                       *p = 0;
    710.                       mhdr = mime_hdr_new(ntmp, strip_ends(q));
    711.                       sk_MIME_HEADER_push(headers, mhdr);
                               ^
    712.                       ntmp = NULL;
    713.                       q = p + 1;

crypto/asn1/asn1_locl.h:93:1: parameter `sk` of sk_MIME_HEADER_push
      91.   DEFINE_STACK_OF(MIME_PARAM)
      92.   typedef struct mime_header_st MIME_HEADER;
      93. > DEFINE_STACK_OF(MIME_HEADER)
      94.   
      95.   /* Month values for printing out times */

crypto/asn1/asn1_locl.h:93:1: when calling `sk_push` here
      91.   DEFINE_STACK_OF(MIME_PARAM)
      92.   typedef struct mime_header_st MIME_HEADER;
      93. > DEFINE_STACK_OF(MIME_HEADER)
      94.   
      95.   /* Month values for printing out times */

crypto/stack/stack.c:259:1: parameter `st` of sk_push
        257.   }
        258.   
        259. > int sk_push(_STACK *st, void *data)
        260.   {
        261.       return (sk_insert(st, data, st->num));

crypto/stack/stack.c:261:13: when calling `sk_insert` here
        259.   int sk_push(_STACK *st, void *data)
        260.   {
        261.       return (sk_insert(st, data, st->num));
                           ^
        262.   }
        263.   

crypto/stack/stack.c:167:1: parameter `st` of sk_insert
          165.   }
          166.   
          167. > int sk_insert(_STACK *st, void *data, int loc)
          168.   {
          169.       char **s;

crypto/stack/stack.c:174:13: when calling `CRYPTO_realloc` here
          172.           return 0;
          173.       if (st->num_alloc <= st->num + 1) {
          174.           s = OPENSSL_realloc((char *)st->data,
                             ^
          175.                               (unsigned int)sizeof(char *) * st->num_alloc * 2);
          176.           if (s == NULL)

crypto/mem.c:166:1: parameter `str` of CRYPTO_realloc
            164.   }
            165.   
            166. > void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
            167.   {
            168.       if (str == NULL)

crypto/mem.c:172:9: when calling `CRYPTO_free` here
            170.   
            171.       if (num == 0) {
            172.           CRYPTO_free(str);
                           ^
            173.           return NULL;
            174.       }

crypto/mem.c:234:1: parameter `str` of CRYPTO_free
              232.   }
              233.   
              234. > void CRYPTO_free(void *str)
              235.   {
              236.   #ifdef CRYPTO_MDEBUG

crypto/mem.c:245:5: was invalidated by call to `free()`
              243.       }
              244.   #else
              245.       free(str);
                         ^
              246.   #endif
              247.   }

crypto/asn1/asn_mime.c:576:20: use-after-lifetime part of the trace starts here
574.       MIME_HEADER *hdr;
575.   
576.       if ((headers = mime_parse_hdr(in)) == NULL) {
                          ^
577.           ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
578.           return 0;

crypto/asn1/asn_mime.c:576:20: passed as argument to `mime_parse_hdr`
  574.       MIME_HEADER *hdr;
  575.   
  576.       if ((headers = mime_parse_hdr(in)) == NULL) {
                            ^
  577.           ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
  578.           return 0;

crypto/asn1/asn_mime.c:677:15: passed as argument to `sk_MIME_HEADER_new`
    675.       int len, state, save_state = 0;
    676.   
    677.       headers = sk_MIME_HEADER_new(mime_hdr_cmp);
                         ^
    678.       if (headers == NULL)
    679.           return NULL;

crypto/asn1/asn_mime.c:677:15: return from call to `sk_MIME_HEADER_new`
    675.       int len, state, save_state = 0;
    676.   
    677.       headers = sk_MIME_HEADER_new(mime_hdr_cmp);
                         ^
    678.       if (headers == NULL)
    679.           return NULL;

crypto/asn1/asn_mime.c:677:5: assigned
    675.       int len, state, save_state = 0;
    676.   
    677.       headers = sk_MIME_HEADER_new(mime_hdr_cmp);
               ^
    678.       if (headers == NULL)
    679.           return NULL;

crypto/asn1/asn_mime.c:576:20: return from call to `mime_parse_hdr`
  574.       MIME_HEADER *hdr;
  575.   
  576.       if ((headers = mime_parse_hdr(in)) == NULL) {
                            ^
  577.           ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
  578.           return 0;

crypto/asn1/asn_mime.c:580:16: when calling `mime_hdr_find` here
  578.           return 0;
  579.       }
  580.       if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
                        ^
  581.           || hdr->value == NULL) {
  582.           ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);

crypto/asn1/asn_mime.c:922:1: parameter `hdrs` of mime_hdr_find
    920.   /* Find a header with a given name (if possible) */
    921.   
    922. > static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
    923.   {
    924.       MIME_HEADER htmp;

crypto/asn1/asn_mime.c:930:12: when calling `sk_MIME_HEADER_value` here
    928.       if (idx < 0)
    929.           return NULL;
    930.       return sk_MIME_HEADER_value(hdrs, idx);
                      ^
    931.   }
    932.   

crypto/asn1/asn1_locl.h:93:1: parameter `sk` of sk_MIME_HEADER_value
      91.   DEFINE_STACK_OF(MIME_PARAM)
      92.   typedef struct mime_header_st MIME_HEADER;
      93. > DEFINE_STACK_OF(MIME_HEADER)
      94.   
      95.   /* Month values for printing out times */

crypto/asn1/asn1_locl.h:93:1: when calling `sk_value` here
      91.   DEFINE_STACK_OF(MIME_PARAM)
      92.   typedef struct mime_header_st MIME_HEADER;
      93. > DEFINE_STACK_OF(MIME_HEADER)
      94.   
      95.   /* Month values for printing out times */

crypto/stack/stack.c:324:1: parameter `st` of sk_value
        322.   }
        323.   
        324. > void *sk_value(const _STACK *st, int i)
        325.   {
        326.       if (!st || (i < 0) || (i >= st->num))

crypto/stack/stack.c:328:12: invalid access occurs here
        326.       if (!st || (i < 0) || (i >= st->num))
        327.           return NULL;
        328.       return st->data[i];
                          ^
        329.   }
        330.   

void *sk_value(const _STACK *st, int i)
{
    if (!st || (i < 0) || (i >= st->num))
        return NULL;
    return st->data[i];
}
['int SMIME_text(BIO *in, BIO *out)\n{\n    char iobuf[4096];\n    int len;\n    STACK_OF(MIME_HEADER) *headers;\n    MIME_HEADER *hdr;\n    if ((headers = mime_parse_hdr(in)) == NULL) {\n        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);\n        return 0;\n    }\n    if ((hdr = mime_hdr_find(headers, "content-type")) == NULL\n        || hdr->value == NULL) {\n        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);\n        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);\n        return 0;\n    }\n    if (strcmp(hdr->value, "text/plain")) {\n        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE);\n        ERR_add_error_data(2, "type: ", hdr->value);\n        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);\n        return 0;\n    }\n    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);\n    while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)\n        BIO_write(out, iobuf, len);\n    if (len < 0)\n        return 0;\n    return 1;\n}', 'static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)\n{\n    char *p, *q, c;\n    char *ntmp;\n    char linebuf[MAX_SMLEN];\n    MIME_HEADER *mhdr = NULL;\n    STACK_OF(MIME_HEADER) *headers;\n    int len, state, save_state = 0;\n    headers = sk_MIME_HEADER_new(mime_hdr_cmp);\n    if (headers == NULL)\n        return NULL;\n    while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {\n        if (mhdr && isspace((unsigned char)linebuf[0]))\n            state = MIME_NAME;\n        else\n            state = MIME_START;\n        ntmp = NULL;\n        for (p = linebuf, q = linebuf; (c = *p) && (c != \'\\r\') && (c != \'\\n\');\n             p++) {\n            switch (state) {\n            case MIME_START:\n                if (c == \':\') {\n                    state = MIME_TYPE;\n                    *p = 0;\n                    ntmp = strip_ends(q);\n                    q = p + 1;\n                }\n                break;\n            case MIME_TYPE:\n                if (c == \';\') {\n                    mime_debug("Found End Value\\n");\n                    *p = 0;\n                    mhdr = mime_hdr_new(ntmp, strip_ends(q));\n                    sk_MIME_HEADER_push(headers, mhdr);\n                    ntmp = NULL;\n                    q = p + 1;\n                    state = MIME_NAME;\n                } else if (c == \'(\') {\n                    save_state = state;\n                    state = MIME_COMMENT;\n                }\n                break;\n            case MIME_COMMENT:\n                if (c == \')\') {\n                    state = save_state;\n                }\n                break;\n            case MIME_NAME:\n                if (c == \'=\') {\n                    state = MIME_VALUE;\n                    *p = 0;\n                    ntmp = strip_ends(q);\n                    q = p + 1;\n                }\n                break;\n            case MIME_VALUE:\n                if (c == \';\') {\n                    state = MIME_NAME;\n                    *p = 0;\n                    mime_hdr_addparam(mhdr, ntmp, strip_ends(q));\n                    ntmp = NULL;\n                    q = p + 1;\n                } else if (c == \'"\') {\n                    mime_debug("Found Quote\\n");\n                    state = MIME_QUOTE;\n                } else if (c == \'(\') {\n                    save_state = state;\n                    state = MIME_COMMENT;\n                }\n                break;\n            case MIME_QUOTE:\n                if (c == \'"\') {\n                    mime_debug("Found Match Quote\\n");\n                    state = MIME_VALUE;\n                }\n                break;\n            }\n        }\n        if (state == MIME_TYPE) {\n            mhdr = mime_hdr_new(ntmp, strip_ends(q));\n            sk_MIME_HEADER_push(headers, mhdr);\n        } else if (state == MIME_VALUE)\n            mime_hdr_addparam(mhdr, ntmp, strip_ends(q));\n        if (p == linebuf)\n            break;\n    }\n    return headers;\n}', 'DEFINE_STACK_OF(MIME_HEADER)', 'int sk_push(_STACK *st, void *data)\n{\n    return (sk_insert(st, data, st->num));\n}', 'int sk_insert(_STACK *st, void *data, int loc)\n{\n    char **s;\n    if (st == NULL)\n        return 0;\n    if (st->num_alloc <= st->num + 1) {\n        s = OPENSSL_realloc((char *)st->data,\n                            (unsigned int)sizeof(char *) * st->num_alloc * 2);\n        if (s == NULL)\n            return (0);\n        st->data = s;\n        st->num_alloc *= 2;\n    }\n    if ((loc >= (int)st->num) || (loc < 0))\n        st->data[st->num] = data;\n    else {\n        memmove(&(st->data[loc + 1]),\n                &(st->data[loc]), sizeof(char *) * (st->num - loc));\n        st->data[loc] = data;\n    }\n    st->num++;\n    st->sorted = 0;\n    return (st->num);\n}', 'void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)\n{\n    if (str == NULL)\n        return CRYPTO_malloc(num, file, line);\n    if (num == 0) {\n        CRYPTO_free(str);\n        return NULL;\n    }\n    allow_customize = 0;\n#ifdef 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;\n    (void)line;\n#endif\n    return realloc(str, num);\n}', 'void CRYPTO_free(void *str)\n{\n#ifdef CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_free(str, 0);\n        free(str);\n        CRYPTO_mem_debug_free(str, 1);\n    } else {\n        free(str);\n    }\n#else\n    free(str);\n#endif\n}', 'static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)\n{\n    MIME_HEADER htmp;\n    int idx;\n    htmp.name = name;\n    idx = sk_MIME_HEADER_find(hdrs, &htmp);\n    if (idx < 0)\n        return NULL;\n    return sk_MIME_HEADER_value(hdrs, idx);\n}', 'void *sk_value(const _STACK *st, int i)\n{\n    if (!st || (i < 0) || (i >= st->num))\n        return NULL;\n    return st->data[i];\n}']