File curl-CVE-2016-8620.patch of Package curl.openSUSE_Leap_42.3_Update
From 4c402fb6dbb7a56e343ea1bd83f5b5d98760db04 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 3 Oct 2016 17:27:16 +0200
Subject: [PATCH] globbing: prevent out of bounds accesses
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reported-by: Luật Nguyễn
---
src/tool_urlglob.c | 58 ++++++++++++++++++++++++++++++++++--------------------
1 file changed, 37 insertions(+), 21 deletions(-)
Index: curl-7.37.0/src/tool_urlglob.c
===================================================================
--- curl-7.37.0.orig/src/tool_urlglob.c 2016-10-20 16:03:30.320394871 +0200
+++ curl-7.37.0/src/tool_urlglob.c 2016-10-20 16:03:51.180728994 +0200
@@ -191,32 +191,36 @@ static GlobCode glob_range(URLGlob *glob
/* character range detected */
char min_c;
char max_c;
+ char end_c;
int step=1;
pat->type = UPTCharRange;
- rc = sscanf(pattern, "%c-%c", &min_c, &max_c);
+ rc = sscanf(pattern, "%c-%c%c", &min_c, &max_c, &end_c);
- if((rc == 2) && (pattern[3] == ':')) {
- char *endp;
- unsigned long lstep;
- errno = 0;
- lstep = strtoul(&pattern[3], &endp, 10);
- if(errno || (*endp != ']'))
- step = -1;
- else {
- pattern = endp+1;
- step = (int)lstep;
- if(step > (max_c - min_c))
+ if(rc == 3) {
+ if(end_c == ':') {
+ char *endp;
+ unsigned long lstep;
+ errno = 0;
+ lstep = strtoul(&pattern[4], &endp, 10);
+ if(errno || (*endp != ']'))
step = -1;
+ else {
+ pattern = endp+1;
+ step = (int)lstep;
+ if(step > (max_c - min_c))
+ step = -1;
+ }
}
+ else if(end_c != ']')
+ /* then this is wrong */
+ rc = 0;
}
- else
- pattern += 4;
*posp += (pattern - *patternp);
- if((rc != 2) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) ||
+ if((rc != 3) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) ||
(step < 0) )
/* the pattern is not well-formed */
return GLOBERROR("bad range", *posp, GLOB_ERROR);
@@ -259,6 +263,12 @@ static GlobCode glob_range(URLGlob *glob
endp = NULL;
else {
pattern = endp+1;
+ while(*pattern && ISBLANK(*pattern))
+ pattern++;
+ if(!ISDIGIT(*pattern)) {
+ endp = NULL;
+ goto fail;
+ }
errno = 0;
max_n = strtoul(pattern, &endp, 10);
if(errno || (*endp == ':')) {
@@ -278,7 +288,8 @@ static GlobCode glob_range(URLGlob *glob
endp = NULL;
}
}
-
+
+ fail:
*posp += (pattern - *patternp);
if(!endp || (min_n > max_n) || (step_n > (max_n - min_n)))
@@ -423,6 +434,7 @@ int glob_url(URLGlob** glob, char* url,
glob_buffer = malloc(strlen(url) + 1);
if(!glob_buffer)
return CURLE_OUT_OF_MEMORY;
+ glob_buffer[0]=0;
glob_expand = calloc(1, sizeof(URLGlob));
if(!glob_expand) {
@@ -542,20 +554,25 @@ int glob_next_url(char **globbed, URLGlo
switch(pat->type) {
case UPTSet:
if(pat->content.Set.elements) {
- len = strlen(pat->content.Set.elements[pat->content.Set.ptr_s]);
snprintf(buf, buflen, "%s",
pat->content.Set.elements[pat->content.Set.ptr_s]);
+ len = strlen(buf);
buf += len;
buflen -= len;
}
break;
case UPTCharRange:
- *buf++ = pat->content.CharRange.ptr_c;
+ if(buflen) {
+ *buf++ = pat->content.CharRange.ptr_c;
+ *buf = '\0';
+ buflen--;
+ }
break;
case UPTNumRange:
- len = snprintf(buf, buflen, "%0*ld",
- pat->content.NumRange.padlength,
- pat->content.NumRange.ptr_n);
+ snprintf(buf, buflen, "%0*ld",
+ pat->content.NumRange.padlength,
+ pat->content.NumRange.ptr_n);
+ len = strlen(buf);
buf += len;
buflen -= len;
break;
@@ -564,7 +581,6 @@ int glob_next_url(char **globbed, URLGlo
return CURLE_FAILED_INIT;
}
}
- *buf = '\0';
*globbed = strdup(glob->glob_buffer);
if(!*globbed)