Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashed at Curl_http_bodysend #12410

Closed
yushicheng7788 opened this issue Nov 27, 2023 · 5 comments
Closed

Crashed at Curl_http_bodysend #12410

yushicheng7788 opened this issue Nov 27, 2023 · 5 comments
Labels

Comments

@yushicheng7788
Copy link

I did this

I use CURLOPT_HTTPPOST to send files, but curl crashed. I think it is caused by the following part of the code.

/* Convert the form structure into a mime structure, then keep
       the conversion */
    if(!data->state.formp) {
      data->state.formp = calloc(sizeof(curl_mimepart), 1);
      if(!data->state.formp)
        return CURLE_OUT_OF_MEMORY;
      Curl_mime_cleanpart(data->state.formp);
      result = Curl_getformdata(data, data->state.formp, data->set.httppost,
                                data->state.fread_func, data->state.seek_func);
      if(result)
        return result;
      data->state.mimepost = data->state.formp;
    }

If Curl_getformdata() returns any error, which will cause data->state.mimepost = data->state.formp; not executed. But if I sent this request again, data->state.formp is not NULL, and data->state.mimepost is NULL, which cause a crash. Is there any optimization method in this case?

I expected the following

Curl will not crash in this case.

curl/libcurl version

8.4.0

operating system

MacOS

@yushicheng7788
Copy link
Author

Can we call Curl_safefree(data->state.formp); when Curl_getformdata return non-zero value to fix this crash?

@bagder bagder added the crash label Nov 27, 2023
@bagder
Copy link
Member

bagder commented Nov 27, 2023

Can you provide us an example that reproduces this problem?

@yushicheng7788
Copy link
Author

int main(int argc, char** argv)
{
    CURLM *cm;
    CURLMsg *msg;
    unsigned int transfers = 0;
    int msgs_left = -1;
    int left = 1;

    curl_global_init(CURL_GLOBAL_ALL);
    cm = curl_multi_init();
    
    CURL *eh = curl_easy_init();
    curl_easy_setopt(eh, CURLOPT_URL, _T("http://localhost:9093/micro/all"));
    struct curl_httppost *lastptr=NULL;
    struct curl_httppost *m_formpost=NULL;
    curl_formadd(&m_formpost,
        &lastptr,
        CURLFORM_COPYNAME, "file",
        CURLFORM_FILE, CMM_T2A(_T("asdwq/usr/bin/zip")),
        CURLFORM_END);
    curl_easy_setopt(eh, CURLOPT_HTTPPOST, m_formpost);
    curl_multi_add_handle(cm, eh);
    
    do {
        int still_alive = 1;
        curl_multi_perform(cm, &still_alive);
        while((msg = curl_multi_info_read(cm, &msgs_left))) {
          if(msg->msg == CURLMSG_DONE) {
            char *url;
            CURL *e = msg->easy_handle;
            curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
            fprintf(stderr, "R: %d - %s <%s>\n",
                    msg->data.result, curl_easy_strerror(msg->data.result), url);
            left--;
          }
          else {
            fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
          }
        }
        if(left)
          curl_multi_wait(cm, NULL, 0, 1000, NULL);
    } while(left);
    int still_alive = 0;
    curl_multi_remove_handle(cm, eh);
    CURLMcode ret = curl_multi_add_handle(cm, eh);
    do {
        int still_alive = 1;
        left = 1;
        curl_multi_perform(cm, &still_alive);
        while((msg = curl_multi_info_read(cm, &msgs_left))) {
          if(msg->msg == CURLMSG_DONE) {
            char *url;
            CURL *e = msg->easy_handle;
            curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
            fprintf(stderr, "R: %d - %s <%s>\n",
                    msg->data.result, curl_easy_strerror(msg->data.result), url);
            left--;
          }
          else {
            fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
          }
        }
        if(left)
          curl_multi_wait(cm, NULL, 0, 1000, NULL);
    } while(left);
    curl_multi_cleanup(cm);
    curl_global_cleanup();

    return EXIT_SUCCESS;
}

This is a simplified example, although it looks strange, but curl will crash in Curl_http_bodysend().

@yushicheng7788
Copy link
Author

"asdwq/usr/bin/zip" not existed on my computer, so Curl_getformdata will return CURLE_READ_ERROR.

@bagder bagder removed the needs-info label Nov 28, 2023
@bagder
Copy link
Member

bagder commented Nov 28, 2023

Thanks, that reproduces for me as well!

bagder added a commit that referenced this issue Nov 28, 2023
Based-on-work-by: yushicheng7788 on github
Fixes #12410
bagder added a commit that referenced this issue Nov 28, 2023
bagder added a commit that referenced this issue Nov 28, 2023
Based-on-work-by: yushicheng7788 on github
Fixes #12410
bagder added a commit that referenced this issue Nov 28, 2023
@bagder bagder closed this as completed in 34e3199 Nov 28, 2023
bagder added a commit that referenced this issue Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants