Menu

#413 storage leak in ftp.c

closed-works-for-me
ftp (93)
7
2013-06-21
2004-04-14
Anonymous
No

Storage leak in ftp.c.
Tested against 7.11.1, using libcurl in Windows.
Submitted by mbp
at cadalog hyphen inc dot com.

In ftp.c, the lines 2400-2405 are:
else
freedirs(ftp);

ftp->ctl_valid = TRUE;
return retcode;
}

They should be:
else {
freedirs(ftp);
if(ftp->file) {
free(ftp->file);
ftp->file = NULL;
}
}

ftp->ctl_valid = TRUE;
return retcode;
}

If you check the mtime of a file on a FTP server, and the
file does not exist (and the FTP server does exist), then
ftp->file is not freed.

example code:
curl_easy_setopt(m_curlHandle, CURLOPT_URL, "ftp:
//xxx.yyy/zzz");
curl_easy_setopt(m_curlHandle, CURLOPT_FILETIME,
1);
curl_easy_setopt(m_curlHandle, CURLOPT_NOBODY,
1);
int rc = curl_easy_perform(m_curlHandle);

Discussion

  • Daniel Stenberg

    Daniel Stenberg - 2004-04-14

    Logged In: YES
    user_id=1110

    How can you tell this is a leak?

    I added a test case (511) that uses these libcurl options
    and that does this operation on a missing file on an
    existing FTP server. It frees the used memory just fine.

    The test program I used looks like this:

    http://curl.haxx.se/lxr/source/tests/libtest/lib511.c

     
  • Daniel Stenberg

    Daniel Stenberg - 2004-04-14
    • milestone: 101008 --> bad_behaviour
    • priority: 5 --> 7
    • status: open --> open-works-for-me
     
  • Marlin

    Marlin - 2004-04-14

    Logged In: YES
    user_id=1021195

    You wrote:
    >How can you tell this is a leak?

    Good question. I am using libcurl in a larger project compiled
    with MSVC 6. The run-time system reports storage leaks
    when a debug version of an application exits. I tracked it to
    the code I mentioned originally.

    The failing case is (of course) more complicated, and I may
    have to build my own test case. First of all, I use the same
    curl_handle more than once. In the case where it fails, I
    check mtime for the same file twice, one right after another.
    The first time, ftp->file is not freed. The second check, which
    immediately follows, clobbers the contents of ftp->file at line
    2367:
    ftp->file = cur_pos; /* the rest is the file name */

    I found this originally by generating an error if ftp->file was not
    zero when line 2367 was executed.

    My original example was too simple. This is a better synopsis
    of the actual code:

    m\_curlHandle = curl\_easy\_init\(\);
    
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_URL, aquery\);
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_USERPWD,
    

    (void *)apasswd);
    curl_easy_setopt(m_curlHandle, CURLOPT_FILETIME, 1);
    curl_easy_setopt(m_curlHandle, CURLOPT_NOBODY, 1);

    int rc = curl\_easy\_perform\(m\_curlHandle\);
    long mtime = 0;
    if \(rc == CURLE\_OK\) \{
        curl\_easy\_getinfo \(m\_curlHandle, CURLINFO\_FILETIME,
    

    &mtime);
    }

    /\* cleanup \*/
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_URL, NULL\);
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_USERPWD,
    

    NULL);
    curl_easy_setopt(m_curlHandle, CURLOPT_FILETIME, 0);
    curl_easy_setopt(m_curlHandle, CURLOPT_NOBODY, 0);

    \[other \(non-cURL\) stuff happens ...\]
    
    /\* second time through... \*/
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_URL, aquery\);
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_USERPWD,
    

    (void *)apasswd);
    curl_easy_setopt(m_curlHandle, CURLOPT_FILETIME, 1);
    curl_easy_setopt(m_curlHandle, CURLOPT_NOBODY, 1);

    rc = curl\_easy\_perform\(m\_curlHandle\);
    long mtime = 0;
    if \(rc == CURLE\_OK\) \{
        curl\_easy\_getinfo \(m\_curlHandle, CURLINFO\_FILETIME,
    

    &mtime);
    }

    /\* cleanup \*/
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_URL, NULL\);
    curl\_easy\_setopt\(m\_curlHandle, CURLOPT\_USERPWD,
    

    NULL);
    curl_easy_setopt(m_curlHandle, CURLOPT_FILETIME, 0);
    curl_easy_setopt(m_curlHandle, CURLOPT_NOBODY, 0);

    \[...\]
    

    The ftp->file value is clobbered during the second
    curl_easy_perform call.

    I will try to create a small test case that repeats this
    behavior.

    But you can also examine the code and see that this is a
    problem, even without a test case. In the Curl_ftp function,
    both ftp->dirs[] and ftp->file are set to allocated strings. In
    the error handling at the very end of the function, the strings
    in ftp->dirs[] are freed, but not ftp->file.

     
  • Daniel Stenberg

    Daniel Stenberg - 2004-04-15

    Logged In: YES
    user_id=1110

    I replied to this in a mail and I cc'ed the libcurl mailing
    list.

     
  • Daniel Stenberg

    Daniel Stenberg - 2004-04-19

    Logged In: YES
    user_id=1110

    No response and not able to repeat.

     
  • Daniel Stenberg

    Daniel Stenberg - 2004-04-19
    • status: open-works-for-me --> closed-works-for-me
     
MongoDB Logo MongoDB