diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2013-05-07 16:19:59 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2013-05-07 16:19:59 +0000 |
commit | a3699b1e05b1fc1ace7e10e2c21176a8bbe4cca0 (patch) | |
tree | d4615e2506a200f5c8dd720e2d4502eebbbbc342 /usr.sbin/relayd | |
parent | 703f978c7d0b7abfa2a597fa0aa135dae74f1b7a (diff) |
- Add a simple check to prevent that the client-provided hex HTTP chunk size
turns our signed input variable into a negative number. This prevents that
a chunked HTTP connection could break its own state machine and turn into
a stalled state. The bug doesn't harm other connections or relayd itself.
- Use a 64bit variable to allow theoretical large chunks.
- Fix a comment.
ok tedu@
Diffstat (limited to 'usr.sbin/relayd')
-rw-r--r-- | usr.sbin/relayd/relay_http.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/usr.sbin/relayd/relay_http.c b/usr.sbin/relayd/relay_http.c index d386de73f66..00591eb62a5 100644 --- a/usr.sbin/relayd/relay_http.c +++ b/usr.sbin/relayd/relay_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay_http.c,v 1.12 2013/04/20 17:41:33 deraadt Exp $ */ +/* $OpenBSD: relay_http.c,v 1.13 2013/05/07 16:19:58 reyk Exp $ */ /* * Copyright (c) 2006 - 2012 Reyk Floeter <reyk@openbsd.org> @@ -443,7 +443,7 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) struct rsession *con = cre->con; struct evbuffer *src = EVBUFFER_INPUT(bev); char *line; - long lval; + long long llval; size_t size; getmonotime(&con->se_tv_last); @@ -485,8 +485,11 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) goto next; } - /* Read prepended chunk size in hex, ingore the trailer */ - if (sscanf(line, "%lx", &lval) != 1) { + /* + * Read prepended chunk size in hex, ignore the trailer. + * The returned signed value must not be negative. + */ + if (sscanf(line, "%llx", &llval) != 1 || llval < 0) { free(line); relay_close(con, "invalid chunk size"); return; @@ -500,7 +503,7 @@ relay_read_httpchunks(struct bufferevent *bev, void *arg) free(line); /* Last chunk is 0 bytes followed by optional trailer */ - if ((cre->toread = lval) == 0) { + if ((cre->toread = llval) == 0) { DPRINTF("%s: last chunk", __func__); cre->toread = TOREAD_HTTP_CHUNK_TRAILER; } |