From b02d889b7e25f38694cf356449f4d249a9e07fec Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sat, 12 Nov 2022 11:33:23 +0300 Subject: [PATCH] Stricter integers parsing --- CHANGES | 1 + dht-bootstrap.c | 39 +++++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index b1c7181..fd07a40 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ * Privilege-separated packets sender * FreeBSD Capsicum sandboxing * poll() replaced with kqueue() + * stricter bencoded integers parser 2022-11-09: diff --git a/dht-bootstrap.c b/dht-bootstrap.c index 9b6f714..977d966 100644 --- a/dht-bootstrap.c +++ b/dht-bootstrap.c @@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include #include #include @@ -121,6 +122,20 @@ getAddr(const struct sockaddr *sa, const socklen_t saLen) return addr; } +static bool +stricttol(const char *p, unsigned long *l, char **q) +{ + if ((isdigit((int)(p[0])) == 0) || (p[0] == '0')) + return false; + errno = 0; + *l = strtoul(p, q, 10); + if (errno != 0) { + perror("strtoul()"); + return false; + } + return true; +} + static int parse_message( const unsigned char *buf, @@ -162,8 +177,8 @@ parse_message( if (tid_return) { p = memmem(buf, buflen, "1:t", 3); if (p) { - l = strtoul((const char *)p + 3, &q, 10); - if (q && *q == ':' && l > 0 && l < *tid_len) { + if (stricttol((const char *)p + 3, &l, &q) && (q && *q == ':') && + (l > 0 && l < *tid_len)) { CHECK(q + 1, l); memcpy(tid_return, q + 1, l); *tid_len = l; @@ -192,8 +207,8 @@ parse_message( if (port_return) { p = memmem(buf, buflen, "porti", 5); if (p) { - l = strtoul((const char *)p + 5, &q, 10); - if (q && *q == 'e' && l > 0 && l < 0x10000) + if (stricttol((const char *)p + 5, &l, &q) && (q && *q == 'e') && + (l > 0 && l < 0x10000)) *port_return = (unsigned short)l; else *port_return = 0; @@ -212,8 +227,8 @@ parse_message( if (token_return) { p = memmem(buf, buflen, "5:token", 7); if (p) { - l = strtoul((const char *)p + 7, &q, 10); - if (q && *q == ':' && l > 0 && l < *token_len) { + if (stricttol((const char *)p + 7, &l, &q) && (q && *q == ':') && + (l > 0 && l < *token_len)) { CHECK(q + 1, l); memcpy(token_return, q + 1, l); *token_len = l; @@ -226,8 +241,8 @@ parse_message( if (nodes_len) { p = memmem(buf, buflen, "5:nodes", 7); if (p) { - l = strtoul((const char *)p + 7, &q, 10); - if (q && *q == ':' && l > 0 && l < *nodes_len) { + if (stricttol((const char *)p + 7, &l, &q) && (q && *q == ':') && + (l > 0 && l < *nodes_len)) { CHECK(q + 1, l); memcpy(nodes_return, q + 1, l); *nodes_len = l; @@ -240,8 +255,8 @@ parse_message( if (nodes6_len) { p = memmem(buf, buflen, "6:nodes6", 8); if (p) { - l = strtoul((const char *)p + 8, &q, 10); - if (q && *q == ':' && l > 0 && l < *nodes6_len) { + if (stricttol((const char *)p + 8, &l, &q) && (q && *q == ':') && + (l > 0 && l < *nodes6_len)) { CHECK(q + 1, l); memcpy(nodes6_return, q + 1, l); *nodes6_len = l; @@ -257,8 +272,8 @@ parse_message( size_t i = p - buf + 9; unsigned long j = 0, j6 = 0; for (;;) { - l = strtoul((const char *)buf + i, &q, 10); - if (q && *q == ':' && l > 0) { + if (stricttol((const char *)buf + i, &l, &q) && (q && *q == ':') && + (l > 0)) { CHECK(q + 1, l); if (l == 6) { if (j + l > *values_len) -- 2.44.0