]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: hpack: reject invalid header index
authorWilly Tarreau <w@1wt.eu>
Sun, 3 Dec 2017 11:12:17 +0000 (12:12 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 3 Dec 2017 20:08:39 +0000 (21:08 +0100)
If the hpack decoder sees an invalid header index, it emits value
"### ERR ###" that was used during debugging instead of rejecting the
block. This is harmless, and was detected by h2spec.

To backport to 1.8.

include/common/hpack-tbl.h
src/hpack-dec.c

index 5de9d201e84c2bbc0fc9c8060492327f51cfd5d9..824c40018ee642524010ae426e1bda33b2445660 100644 (file)
@@ -154,6 +154,12 @@ static inline const struct hpack_dte *hpack_get_dte(const struct hpack_dht *dht,
        return &dht->dte[idx];
 }
 
+/* returns non-zero if <idx> is valid for table <dht> */
+static inline int hpack_valid_idx(const struct hpack_dht *dht, uint16_t idx)
+{
+       return idx < dht->used + HPACK_SHT_SIZE;
+}
+
 /* return a pointer to the header name for entry <dte>. */
 static inline struct ist hpack_get_name(const struct hpack_dht *dht, const struct hpack_dte *dte)
 {
index 1a776bca76c8d0df745a5c153d4c3c01afbae8be..0515d011be3fd4691a89d214e5e4c0de1cb14025 100644 (file)
@@ -177,6 +177,11 @@ int hpack_decode_frame(struct hpack_dht *dht, const uint8_t *raw, uint32_t len,
                                goto leave;
                        }
 
+                       if (!hpack_valid_idx(dht, idx)) {
+                               ret = -HPACK_ERR_TOO_LARGE;
+                               goto leave;
+                       }
+
                        value = hpack_alloc_string(tmp, idx, hpack_idx_to_value(dht, idx));
                        if (!value.ptr) {
                                ret = -HPACK_ERR_TOO_LARGE;
@@ -316,6 +321,11 @@ int hpack_decode_frame(struct hpack_dht *dht, const uint8_t *raw, uint32_t len,
                                goto leave;
                        }
 
+                       if (!hpack_valid_idx(dht, idx)) {
+                               ret = -HPACK_ERR_TOO_LARGE;
+                               goto leave;
+                       }
+
                        /* retrieve value */
                        huff = *raw & 0x80;
                        vlen = get_var_int(&raw, &len, 7);