From 71da91453899ba20b28ee9712620e323145a0ee5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 Oct 2016 18:56:45 +0200 Subject: [PATCH] unescape: avoid integer overflow CVE-2016-8622 Bug: https://curl.haxx.se/docs/adv_20161102H.html Reported-by: Cure53 --- docs/libcurl/curl_easy_unescape.3 | 7 +++++-- lib/dict.c | 10 +++++----- lib/escape.c | 10 ++++++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/libcurl/curl_easy_unescape.3 b/docs/libcurl/curl_easy_unescape.3 index 06fd6fc..50ce97d 100644 --- a/docs/libcurl/curl_easy_unescape.3 +++ b/docs/libcurl/curl_easy_unescape.3 @@ -3,11 +3,11 @@ .\" * Project ___| | | | _ \| | .\" * / __| | | | |_) | | .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms .\" * are also available at https://curl.haxx.se/docs/copyright.html. .\" * @@ -38,11 +38,14 @@ their binary versions. If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_unescape(3)\fP will use strlen() on the input \fIurl\fP string to find out the size. If \fBoutlength\fP is non-NULL, the function will write the length of the returned string in the integer it points to. This allows an escaped string -containing %00 to still get used properly after unescaping. +containing %00 to still get used properly after unescaping. Since this is a +pointer to an \fIint\fP type, it can only return a value up to INT_MAX so no +longer string can be unescaped if the string length is returned in this +parameter. You must \fIcurl_free(3)\fP the returned string when you're done with it. .SH AVAILABILITY Added in 7.15.4 and replaces the old \fIcurl_unescape(3)\fP function. .SH RETURN VALUE diff --git a/lib/dict.c b/lib/dict.c index a7b5965..48a4e0a 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -3,11 +3,11 @@ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at https://curl.haxx.se/docs/copyright.html. * @@ -50,11 +50,11 @@ #include "urldata.h" #include #include "transfer.h" #include "sendf.h" - +#include "escape.h" #include "progress.h" #include "strequal.h" #include "dict.h" #include "rawstr.h" #include "curl_memory.h" @@ -94,16 +94,16 @@ const struct Curl_handler Curl_handler_dict = { static char *unescape_word(struct Curl_easy *data, const char *inputbuff) { char *newp; char *dictp; char *ptr; - int len; + size_t len; char ch; int olen=0; - newp = curl_easy_unescape(data, inputbuff, 0, &len); - if(!newp) + CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE); + if(!newp || result) return NULL; dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */ if(dictp) { /* According to RFC2229 section 2.2, these letters need to be escaped with diff --git a/lib/escape.c b/lib/escape.c index e61260d..6657007 100644 --- a/lib/escape.c +++ b/lib/escape.c @@ -222,12 +222,18 @@ char *curl_easy_unescape(struct Curl_easy *data, const char *string, size_t outputlen; CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen, FALSE); if(res) return NULL; - if(olen) - *olen = curlx_uztosi(outputlen); + + if(olen) { + if(outputlen <= (size_t) INT_MAX) + *olen = curlx_uztosi(outputlen); + else + /* too large to return in an int, fail! */ + Curl_safefree(str); + } } return str; } /* For operating systems/environments that use different malloc/free -- 2.9.3