memory leak when timeout expired during POST request #147

Closed
mpromonet opened this Issue Mar 5, 2015 · 2 comments

Projects

None yet

2 participants

@mpromonet

Using a simple example based on postit2.c :

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
int main(int argc, char *argv[])
{
  CURL *curl;
  CURLcode res;
  struct curl_httppost *formpost=NULL;
  struct curl_httppost *lastptr=NULL;
  struct curl_slist *headerlist=NULL;
  static const char buf[] = "Expect:";

  curl_global_init(CURL_GLOBAL_ALL);
  curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END);
  curl = curl_easy_init();
  headerlist = curl_slist_append(headerlist, buf); 
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:12345");
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);

    res = curl_easy_perform(curl);
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

    curl_easy_cleanup(curl);
    curl_formfree(formpost);
    curl_slist_free_all (headerlist);
  }
  return 0;
}

Starting a netcat command nc -l -p 12345 in order to read HTTP request without answering, running the previous sample under valgrind report the following memory leak :

==7666== 495 (32 direct, 463 indirect) bytes in 1 blocks are definitely lost in loss record 602 of 641
==7666==    at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7666==    by 0x4073BC: AddFormData (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4075BF: AddFormDataf (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x40860D: Curl_getformdata (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x419F99: Curl_http (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4253FA: Curl_do (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4102CE: multi_runsingle (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4109BC: curl_multi_perform (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x40BB0A: curl_easy_perform (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x40714E: main (in /mnt/DOWNLOAD/curl/docs/examples/postit2)

Investigating show that this was introduced by the commit 1342a96. There is no leak with curl-7_39_0, and there is a leak with curl-7_40_0.

A possible fix seems to add in lib/multi.c line 1019 (in order to free what allocate Curl_getformdata) :

  1018    result = CURLE_OPERATION_TIMEDOUT;
  1019    (void)Curl_done(&data->easy_conn, data->result, TRUE); 
  1020    /* Skip the statemachine and go directly to error handling section. */
  1021    goto statemachine_end;
@bagder bagder self-assigned this Mar 5, 2015
@bagder bagder added the memory-leak label Mar 5, 2015
@bagder
Member
bagder commented Mar 5, 2015

Thanks, looks like a fine fix to me. Running some local tests to verify nothing breaks.

@bagder bagder added a commit that referenced this issue Mar 5, 2015
@bagder bagder multi: fix memory-leak on timeout (regression)
Since 1342a96, a timeout detected in the multi state machine didn't
necesarily clear everything up, like formpost data.

Bug: #147
Reported-by: Michel Promonet
Patched-by: Michel Promonet
492dfca
@bagder
Member
bagder commented Mar 5, 2015

Thanks, pushed fix as commit 492dfca

@bagder bagder closed this Mar 5, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment