Lucene search

K
hackerone1wcH1:547630
HistoryApr 24, 2019 - 12:05 p.m.

curl: An integer overflow found in /lib/urlapi.c

2019-04-2412:05:35
1wc
hackerone.com
39

0.017 Low

EPSS

Percentile

87.7%

Summary:

libcurl contains a heap-based buffer overrun in /lib/urlapi.c. A similiar issue to CVE-2018-14618.

Steps To Reproduce:

analysis

I found a potential integer overflow which may lead to a buffer overrun in /curl/lib/urlapi.c. In function seturl, urllen was multiplied by 2 and then passed to malloc. So an integer overflow will happen when the url is as long as 2GB in a 32 bit OS.

static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
{
  char *path;
  bool path_alloced = FALSE;
  char *hostname;
  char *query = NULL;
  char *fragment = NULL;
  CURLUcode result;
  bool url_has_scheme = FALSE;
  char schemebuf[MAX_SCHEME_LEN];
  char *schemep = NULL;
  size_t schemelen = 0;
  size_t urllen;
  const struct Curl_handler *h = NULL;

  if(!url)
    return CURLUE_MALFORMED_INPUT;

  /*************************************************************
   * Parse the URL.
   ************************************************************/
  /* allocate scratch area */
  urllen = strlen(url);
  path = u->scratch = malloc(urllen * 2 + 2); <= overflow here

The url was passed by parseurl to seturl.

static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
{
  CURLUcode result = seturl(url, u, flags);
  if(result) {
    free_urlhandle(u);
    memset(u, 0, sizeof(struct Curl_URL));
  }
  return result;
}

And the parseurl was called when do curl_url_set and execute the parse of url. If someone use libcurl to code, and call curl_url_set with a extreme long url, it might be triggered.

CURLUcode curl_url_set(CURLU *u, CURLUPart what,
                       const char *part, unsigned int flags)
......
case CURLUPART_URL: {
    /*
     * Allow a new URL to replace the existing (if any) contents.
     *
     * If the existing contents is enough for a URL, allow a relative URL to
     * replace it.
     */
    CURLUcode result;
    char *oldurl;
    char *redired_url;
    CURLU *handle2;

    if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN)) {
      handle2 = curl_url();
      if(!handle2)
        return CURLUE_OUT_OF_MEMORY;
      result = parseurl(part, handle2, flags); <= call parseurl
      if(!result)
        mv_urlhandle(handle2, u);
      else
        curl_url_cleanup(handle2);
      return result;
    }

Impact

It might leads to a crash or some other impact.