From 48aca2de80a7dd73f8f3a461c7f7ed47b6082766 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 3 Dec 2021 17:07:55 +0100 Subject: iptopt: fix crash with invalid field/type combo % nft describe ip option rr value segmentation fault after this fix, this exits with 'Error: unknown ip option type/field'. Problem is that 'rr' doesn't have a value template, so the template struct is all-zeroes, so we crash when trying to use tmpl->dtype (its NULL). Furthermore, expr_describe tries to print expr->identifier but expr is exthdr, not symbol: ->identifier contains garbage. Signed-off-by: Florian Westphal --- src/expression.c | 5 ++++- src/ipopt.c | 3 +++ src/parser_bison.y | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/expression.c b/src/expression.c index a6bde70..ccc4d92 100644 --- a/src/expression.c +++ b/src/expression.c @@ -138,7 +138,10 @@ void expr_describe(const struct expr *expr, struct output_ctx *octx) } else { nft_print(octx, "%s expression, datatype %s (%s)", expr_name(expr), dtype->name, dtype->desc); - } + + if (dtype == &invalid_type) + return; + } if (dtype->basetype != NULL) { nft_print(octx, " (basetype "); diff --git a/src/ipopt.c b/src/ipopt.c index b3d0279..b851f2b 100644 --- a/src/ipopt.c +++ b/src/ipopt.c @@ -97,6 +97,9 @@ struct expr *ipopt_expr_alloc(const struct location *loc, uint8_t type, if (!tmpl) return NULL; + if (!tmpl->len) + return NULL; + expr = expr_alloc(loc, EXPR_EXTHDR, tmpl->dtype, BYTEORDER_BIG_ENDIAN, tmpl->len); expr->exthdr.desc = desc; diff --git a/src/parser_bison.y b/src/parser_bison.y index 8af5c7e..71fb2d2 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -4726,6 +4726,10 @@ ip_hdr_expr : IP ip_hdr_field | IP OPTION ip_option_type ip_option_field { $$ = ipopt_expr_alloc(&@$, $3, $4, 0); + if (!$$) { + erec_queue(error(&@1, "unknown ip option type/field"), state->msgs); + YYERROR; + } } | IP OPTION ip_option_type { -- 2.23.0