]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug #2155: Assertion failures on malformed Content-Range response headers
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Thu, 26 Nov 2009 02:04:11 +0000 (03:04 +0100)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Thu, 26 Nov 2009 02:04:11 +0000 (03:04 +0100)
A number of conditions with malformed Content-Range headers were
not trapped properly triggering odd conditions in the code.

src/HttpHdrContRange.cc

index 33ee1a0f53d23f5cb3161f8ffbd2cf187da7281a..c0af6ad673cfe1a901d710d4fa9ab41b874acfe9 100644 (file)
@@ -84,22 +84,34 @@ httpHdrRangeRespSpecParseInit(HttpHdrRangeSpec * spec, const char *field, int fl
     if (!httpHeaderParseOffset(field, &spec->offset))
         return 0;
 
+    /* Additional check for BUG2155 - there MUST BE first-byte-pos and it MUST be positive*/
+    if (spec->offset < 0) {
+        debugs(68, 2, "invalid (no first-byte-pos or it is negative) resp-range-spec near: '" << field << "'");
+        return 0;
+    }
+
     p++;
 
     /* do we have last-pos ? */
-    if (p - field < flen) {
-        int64_t last_pos;
+    if (p - field >= flen) {
+        debugs(68, 2, "invalid (no last-byte-pos) resp-range-spec near: '" << field << "'");
+        return 0;
+    }
+
+    int64_t last_pos;
 
-        if (!httpHeaderParseOffset(p, &last_pos))
-            return 0;
+    if (!httpHeaderParseOffset(p, &last_pos))
+        return 0;
 
-        spec->length = size_diff(last_pos + 1, spec->offset);
-        /* Ensure typecast is safe */
-        assert (spec->length >= 0);
+    if (last_pos < spec->offset) {
+        debugs(68, 2, "invalid (negative last-byte-pos) resp-range-spec near: '" << field << "'");
+        return 0;
     }
 
+    spec->length = size_diff(last_pos + 1, spec->offset);
+
     /* we managed to parse, check if the result makes sence */
-    if (known_spec(spec->length) && spec->length == 0) {
+    if (spec->length <= 0) {
         debugs(68, 2, "invalid range (" << spec->offset << " += " <<
                (long int) spec->length << ") in resp-range-spec near: '" << field << "'");
         return 0;
@@ -176,6 +188,14 @@ httpHdrContRangeParseInit(HttpHdrContRange * range, const char *str)
         range->elength = range_spec_unknown;
     else if (!httpHeaderParseOffset(p, &range->elength))
         return 0;
+    else if (range->elength <= 0) {
+        /* Additional paranoidal check for BUG2155 - entity-length MUST be > 0 */
+        debugs(68, 2, "invalid (entity-length is negative) content-range-spec near: '" << str << "'");
+        return 0;
+    } else if (known_spec(range->spec.length) && range->elength < (range->spec.offset + range->spec.length)) {
+        debugs(68, 2, "invalid (range is outside entity-length) content-range-spec near: '" << str << "'");
+        return 0;
+    }
 
     debugs(68, 8, "parsed content-range field: " <<
            (long int) range->spec.offset << "-" <<