commit ed4bc554503d1a18cb6764943eea98aaf43bf2da Author: Nick Mathewson nickm@torproject.org Date: Wed Jun 21 11:10:58 2017 -0400
Replace peek_buf_startswith() with a safe version
It's not okay to assume that the data in a buf_t is contiguous in the first chunk. --- src/or/buffers.c | 17 ++++++++++------- src/or/buffers.h | 5 +++-- 2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/or/buffers.c b/src/or/buffers.c index 060f58c..b071725 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -2024,7 +2024,7 @@ parse_socks_client(const uint8_t *data, size_t datalen,
/** Return true if <b>cmd</b> looks like a HTTP (proxy) request. */ int -peek_buf_has_http_command(buf_t *buf) +peek_buf_has_http_command(const buf_t *buf) { if (peek_buf_startswith(buf, "CONNECT ") || peek_buf_startswith(buf, "DELETE ") || @@ -2036,15 +2036,18 @@ peek_buf_has_http_command(buf_t *buf) }
/** Return 1 iff <b>buf</b> starts with <b>cmd</b>. <b>cmd</b> must be a null - * terminated string */ + * terminated string, of no more than PEEK_BUF_STARTSWITH_MAX bytes. */ int -peek_buf_startswith(buf_t *buf, const char *cmd) +peek_buf_startswith(const buf_t *buf, const char *cmd) { + char tmp[PEEK_BUF_STARTSWITH_MAX]; size_t clen = strlen(cmd); - if (buf->datalen >= clen) - if (!strncasecmp((buf->head)->data, cmd, (size_t) clen)) - return 1; - return 0; + if (BUG(clen > sizeof(tmp))) + return 0; + if (buf->datalen < clen) + return 0; + peek_from_buf(tmp, clen, buf); + return fast_memeq(tmp, cmd, clen); }
/** Return 1 iff buf looks more like it has an (obsolete) v0 controller diff --git a/src/or/buffers.h b/src/or/buffers.h index 5650bea..d884084 100644 --- a/src/or/buffers.h +++ b/src/or/buffers.h @@ -53,8 +53,9 @@ int fetch_from_buf_socks_client(buf_t *buf, int state, char **reason); int fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len);
int peek_buf_has_control0_command(buf_t *buf); -int peek_buf_startswith(buf_t *buf, const char *cmd); -int peek_buf_has_http_command(buf_t *buf); +#define PEEK_BUF_STARTSWITH_MAX 16 +int peek_buf_startswith(const buf_t *buf, const char *cmd); +int peek_buf_has_http_command(const buf_t *buf);
int fetch_ext_or_command_from_buf(buf_t *buf, ext_or_cmd_t **out);
tor-commits@lists.torproject.org