From 1ecc88431777f0013aa29cbcccc041168002dea5 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Fri, 15 Sep 2017 09:27:07 +0200 Subject: [PATCH] core: tcp_read_headers() safety checks for parsed pointer - reset if it is out of read buffer range and the state is H_SKIP_EMPTY (cherry picked from commit f47f42ac12ad111b3bad52aa2d495fbed5ef395d) --- src/core/tcp_read.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/core/tcp_read.c b/src/core/tcp_read.c index 7014353c624..818bc52b7f0 100644 --- a/src/core/tcp_read.c +++ b/src/core/tcp_read.c @@ -428,7 +428,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags) r->state=(newstate); break; \ crlf_default_skip_case; \ } - + #define change_state_case(state0, upper, lower, newstate)\ case state0: \ change_state(upper, lower, newstate); \ @@ -437,6 +437,22 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags) r=&c->req; + if(r->parsedbuf || r->parsed>r->buf+r->b_size) { + if(r->parsedbuf && (unsigned char)r->state==H_SKIP_EMPTY) { + /* give it a chance to parse from beginning */ + LM_WARN("resetting parsed pointer (buf:%p parsed:%p bsize:%u)\n", + r->buf, r->parsed, r->b_size); + r->parsed = r->buf; + } else { + LM_ERR("out of bounds parsed pointer (buf:%p parsed:%p bsize:%u)\n", + r->buf, r->parsed, r->b_size); + r->parsed = r->buf; + r->content_len=0; + r->error=TCP_REQ_BAD_LEN; + r->state=H_SKIP; /* skip state now */ + return -1; + } + } /* if we still have some unparsed part, parse it first, don't do the read*/ if (unlikely(r->parsedpos)){ bytes=0;