[6.0] 8a564bb55 Fix a buffer overflow situation in h2_deliver
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Thu Aug 16 08:53:24 UTC 2018
commit 8a564bb556d4eff6632641cd820d0dbd9dba4459
Author: Dag Haavi Finstad <daghf at varnish-software.com>
Date: Mon Aug 13 11:32:10 2018 +0200
Fix a buffer overflow situation in h2_deliver
This still lacks error handling and thus is not a fix for #2589, but at
least we're not writing past the end of the workspace any more.
diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c
index cb9c7d3f2..a36d657c0 100644
--- a/bin/varnishd/http2/cache_http2_deliver.c
+++ b/bin/varnishd/http2/cache_http2_deliver.c
@@ -160,34 +160,35 @@ h2_minimal_response(struct req *req, uint16_t status)
return (0);
}
-static uint8_t *
-h2_enc_len(uint8_t *p, unsigned bits, unsigned val)
+static int
+h2_enc_len(struct vsb *vsb, unsigned bits, unsigned val, uint8_t b0)
{
assert(bits < 8);
unsigned mask = (1U << bits) - 1U;
if (val >= mask) {
- *p++ |= (uint8_t)mask;
+ AZ(VSB_putc(vsb, b0 | (uint8_t)mask));
val -= mask;
while (val >= 128) {
- *p++ = 0x80 | ((uint8_t)val & 0x7f);
+ AZ(VSB_putc(vsb, 0x80 | ((uint8_t)val & 0x7f)));
val >>= 7;
}
}
- *p++ = (uint8_t)val;
- return (p);
+ AZ(VSB_putc(vsb, (uint8_t)val));
+ return (0);
}
void v_matchproto_(vtr_deliver_f)
h2_deliver(struct req *req, struct boc *boc, int sendbody)
{
ssize_t sz, sz1;
- uint8_t *p;
- unsigned u;
+ unsigned u, l;
+ uint8_t buf[6];
const char *r;
struct http *hp;
struct sess *sp;
struct h2_req *r2;
+ struct vsb resp;
int i, err;
const struct hpack_static *hps;
@@ -198,15 +199,14 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody)
sp = req->sp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- (void)WS_Reserve(req->ws, 0);
- p = (void*)req->ws->f;
+ l = WS_Reserve(req->ws, 0);
+ AN(VSB_new(&resp, req->ws->f, l, VSB_FIXEDLEN));
- p += h2_status(p, req->resp->status);
+ l = h2_status(buf, req->resp->status);
+ AZ(VSB_bcat(&resp, buf, l));
hp = req->resp;
for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
- assert(WS_Inside(req->ws, p, NULL));
-
r = strchr(hp->hd[u].b, ':');
AN(r);
@@ -227,27 +227,24 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody)
VSLb(req->vsl, SLT_Debug,
"HP {%d, \"%s\", \"%s\"} <%s>",
hps->idx, hps->name, hps->val, hp->hd[u].b);
- *p = 0x10;
- p = h2_enc_len(p, 4, hps->idx);
+ AZ(h2_enc_len(&resp, 4, hps->idx, 0x10));
} else {
-
- *p++ = 0x10;
+ AZ(VSB_putc(&resp, 0x10));
sz--;
- p = h2_enc_len(p, 7, sz);
+ AZ(h2_enc_len(&resp, 7, sz, 0));
for (sz1 = 0; sz1 < sz; sz1++)
- *p++ = (uint8_t)tolower(hp->hd[u].b[sz1]);
+ AZ(VSB_putc(&resp, tolower(hp->hd[u].b[sz1])));
}
while (vct_islws(*++r))
continue;
sz = hp->hd[u].e - r;
- p = h2_enc_len(p, 7, sz);
- memcpy(p, r, sz);
- p += sz;
- assert(WS_Inside(req->ws, p, NULL));
+ AZ(h2_enc_len(&resp, 7, sz, 0));
+ AZ(VSB_bcat(&resp, r, sz));
}
- sz = (char*)p - req->ws->f;
+ VSB_finish(&resp);
+ sz = VSB_len(&resp);
AZ(req->wrk->v1l);
More information about the varnish-commit
mailing list