]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8160 Additional vulnerability in json parsing malformed utf encoded chars discover...
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 19 Nov 2015 19:45:04 +0000 (13:45 -0600)
committerMichael Jerris <mike@jerris.com>
Thu, 19 Nov 2015 19:44:55 +0000 (13:44 -0600)
libs/esl/src/esl_json.c
libs/libks/src/ks_json.c
src/switch_json.c

index df5a88135dffa1f5c938ba7d94453f7f8b7190c1..02270a7f713e70856d481d5c96a64961ec240bea 100644 (file)
@@ -150,6 +150,13 @@ static char *print_number(cJSON *item)
        return str;
 }
 
+#define is_hexdigit(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
+static int scan_unicode(const char *ptr, unsigned int *uc)
+{
+       if (!is_hexdigit(*(ptr)) || !is_hexdigit(*(ptr+1)) || !is_hexdigit(*(ptr+2)) || !is_hexdigit(*(ptr+3))) return -1;
+       return sscanf(ptr, "%4x", uc);
+}
+
 /* Parse the input text into an unescaped cstring, and populate item. */
 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 static const char *parse_string(cJSON *item,const char *str)
@@ -177,8 +184,7 @@ static const char *parse_string(cJSON *item,const char *str)
                                case 'r': *ptr2++='\r'; break;
                                case 't': *ptr2++='\t'; break;
                                case 'u':        /* transcode utf16 to utf8. */
-                                       if (sscanf(ptr+1,"%4x",&uc) < 1) break;
-
+                                       if (scan_unicode(ptr+1, &uc) < 1) break;
                                        ptr+=4; /* get the unicode char. */
 
                                        if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)        break;  // check for invalid.
@@ -186,7 +192,7 @@ static const char *parse_string(cJSON *item,const char *str)
                                        if (uc>=0xD800 && uc<=0xDBFF)   // UTF16 surrogate pairs.
                                        {
                                                if (ptr[1]!='\\' || ptr[2]!='u')        break;  // missing second-half of surrogate.
-                                               if (sscanf(ptr+3,"%4x",&uc2) < 1) break;
+                                               if (scan_unicode(ptr+3,&uc2) < 1) break;
                                                ptr+=6;
                                                if (uc2<0xDC00 || uc2>0xDFFF)           break;  // invalid second-half of surrogate.
                                                uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
index 63529e7b5ba1bb5e67a1f86b643ea6b2dd815ac5..4ee4a84ef67a7c92839dceca5533a4a9a0562f3c 100644 (file)
@@ -150,6 +150,13 @@ static char *print_number(cJSON *item)
        return str;
 }
 
+#define is_hexdigit(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
+static int scan_unicode(const char *ptr, unsigned int *uc)
+{
+       if (!is_hexdigit(*(ptr)) || !is_hexdigit(*(ptr+1)) || !is_hexdigit(*(ptr+2)) || !is_hexdigit(*(ptr+3))) return -1;
+       return sscanf(ptr, "%4x", uc);
+}
+
 /* Parse the input text into an unescaped cstring, and populate item. */
 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 static const char *parse_string(cJSON *item,const char *str)
@@ -177,8 +184,7 @@ static const char *parse_string(cJSON *item,const char *str)
                                case 'r': *ptr2++='\r'; break;
                                case 't': *ptr2++='\t'; break;
                                case 'u':        /* transcode utf16 to utf8. */
-                                       if (sscanf(ptr+1,"%4x",&uc) < 1) break;
-
+                                       if (scan_unicode(ptr+1, &uc) < 1) break;
                                        ptr+=4; /* get the unicode char. */
 
                                        if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)        break;  // check for invalid.
@@ -186,7 +192,7 @@ static const char *parse_string(cJSON *item,const char *str)
                                        if (uc>=0xD800 && uc<=0xDBFF)   // UTF16 surrogate pairs.
                                        {
                                                if (ptr[1]!='\\' || ptr[2]!='u')        break;  // missing second-half of surrogate.
-                                               if (sscanf(ptr+3,"%4x",&uc2) < 1) break;
+                                               if (scan_unicode(ptr+3,&uc2) < 1) break;
                                                ptr+=6;
                                                if (uc2<0xDC00 || uc2>0xDFFF)           break;  // invalid second-half of surrogate.
                                                uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
index c3c25364dac78a5c2cbf2da9fc5e7bb377299a3a..2f52967a0b6662aa851fdca89af60d1f5e45106a 100644 (file)
@@ -150,6 +150,13 @@ static char *print_number(cJSON *item)
        return str;
 }
 
+#define is_hexdigit(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
+static int scan_unicode(const char *ptr, unsigned int *uc)
+{
+       if (!is_hexdigit(*(ptr)) || !is_hexdigit(*(ptr+1)) || !is_hexdigit(*(ptr+2)) || !is_hexdigit(*(ptr+3))) return -1;
+       return sscanf(ptr, "%4x", uc);
+}
+
 /* Parse the input text into an unescaped cstring, and populate item. */
 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 static const char *parse_string(cJSON *item,const char *str)
@@ -177,8 +184,7 @@ static const char *parse_string(cJSON *item,const char *str)
                                case 'r': *ptr2++='\r'; break;
                                case 't': *ptr2++='\t'; break;
                                case 'u':        /* transcode utf16 to utf8. */
-                                       if (sscanf(ptr+1,"%4x",&uc) < 1) break;
-
+                                       if (scan_unicode(ptr+1, &uc) < 1) break;
                                        ptr+=4; /* get the unicode char. */
 
                                        if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)        break;  // check for invalid.
@@ -186,7 +192,7 @@ static const char *parse_string(cJSON *item,const char *str)
                                        if (uc>=0xD800 && uc<=0xDBFF)   // UTF16 surrogate pairs.
                                        {
                                                if (ptr[1]!='\\' || ptr[2]!='u')        break;  // missing second-half of surrogate.
-                                               if (sscanf(ptr+3,"%4x",&uc2) < 1) break;
+                                               if (scan_unicode(ptr+3,&uc2) < 1) break;
                                                ptr+=6;
                                                if (uc2<0xDC00 || uc2>0xDFFF)           break;  // invalid second-half of surrogate.
                                                uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);