From be0535f00ba40f777a9f47aa41a98aa48254d37c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 9 Mar 2012 11:50:22 -0500 Subject: [PATCH] Correctly handle broken escape sequences in torrc values Previously, malformatted torrc values could crash us. Patch by Esteban Manchado. Fixes bug 5090; fix on 0.2.0.16-alpha. --- changes/bug5090 | 6 ++++++ src/common/util.c | 24 ++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 changes/bug5090 diff --git a/changes/bug5090 b/changes/bug5090 new file mode 100644 index 0000000000..240d4709f5 --- /dev/null +++ b/changes/bug5090 @@ -0,0 +1,6 @@ + o Minor bugfixes: + - Detect and reject certain misformed escape sequences in configuration + values. Previously, these values would cause us to crash if received + in a torrc file or over an (authenticated) control port. Patch by + Esteban Manchado Velázquez. Fix for bug 5090; bugfix on 0.2.0.16-alpha. + diff --git a/src/common/util.c b/src/common/util.c index 7675ede433..e3cd154b93 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -2212,14 +2212,16 @@ unescape_string(const char *s, char **result, size_t *size_out) case '\"': goto end_of_loop; case '\\': - if ((cp[1] == 'x' || cp[1] == 'X') - && TOR_ISXDIGIT(cp[2]) && TOR_ISXDIGIT(cp[3])) { + if (cp[1] == 'x' || cp[1] == 'X') { + if (!(TOR_ISXDIGIT(cp[2]) && TOR_ISXDIGIT(cp[3]))) + return NULL; cp += 4; } else if (TOR_ISODIGIT(cp[1])) { cp += 2; if (TOR_ISODIGIT(*cp)) ++cp; if (TOR_ISODIGIT(*cp)) ++cp; - } else if (cp[1]) { + } else if (cp[1] == 'n' || cp[1] == 'r' || cp[1] == 't' || cp[1] == '"' + || cp[1] == '\\' || cp[1] == '\'') { cp += 2; } else { return NULL; @@ -2251,9 +2253,19 @@ unescape_string(const char *s, char **result, size_t *size_out) case 'r': *out++ = '\r'; cp += 2; break; case 't': *out++ = '\t'; cp += 2; break; case 'x': case 'X': - *out++ = ((hex_decode_digit(cp[2])<<4) + - hex_decode_digit(cp[3])); - cp += 4; + { + int x1, x2; + + x1 = hex_decode_digit(cp[2]); + x2 = hex_decode_digit(cp[3]); + if (x1 == -1 || x2 == -1) { + tor_free(*result); + return NULL; + } + + *out++ = ((x1<<4) + x2); + cp += 4; + } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':