diff options
-rw-r--r-- | src/meta.c | 29 | ||||
-rw-r--r-- | tests/shell/testcases/bogons/nft-f/tchandle_type_parse_heap_overflow | 6 |
2 files changed, 15 insertions, 20 deletions
@@ -62,50 +62,39 @@ static struct error_record *tchandle_type_parse(struct parse_ctx *ctx, struct expr **res) { uint32_t handle; - char *str = NULL; if (strcmp(sym->identifier, "root") == 0) handle = TC_H_ROOT; else if (strcmp(sym->identifier, "none") == 0) handle = TC_H_UNSPEC; else if (strchr(sym->identifier, ':')) { + char *colon, *end; uint32_t tmp; - char *colon; - - str = xstrdup(sym->identifier); - - colon = strchr(str, ':'); - if (!colon) - goto err; - - *colon = '\0'; errno = 0; - tmp = strtoull(str, NULL, 16); - if (errno != 0) + tmp = strtoul(sym->identifier, &colon, 16); + if (errno != 0 || sym->identifier == colon) goto err; - handle = (tmp << 16); - if (str[strlen(str) - 1] == ':') - goto out; + if (*colon != ':') + goto err; + handle = tmp << 16; errno = 0; - tmp = strtoull(colon + 1, NULL, 16); - if (errno != 0) + tmp = strtoul(colon + 1, &end, 16); + if (errno != 0 || *end) goto err; handle |= tmp; } else { handle = strtoull(sym->identifier, NULL, 0); } -out: - free(str); + *res = constant_expr_alloc(&sym->location, sym->dtype, BYTEORDER_HOST_ENDIAN, sizeof(handle) * BITS_PER_BYTE, &handle); return NULL; err: - free(str); return error(&sym->location, "Could not parse %s", sym->dtype->desc); } diff --git a/tests/shell/testcases/bogons/nft-f/tchandle_type_parse_heap_overflow b/tests/shell/testcases/bogons/nft-f/tchandle_type_parse_heap_overflow new file mode 100644 index 00000000..ea7186bf --- /dev/null +++ b/tests/shell/testcases/bogons/nft-f/tchandle_type_parse_heap_overflow @@ -0,0 +1,6 @@ +table t { +map m { + type ipv4_addr : classid + elements = { 1.1.26.3 : ::a } +} +} |