]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
exthdr: Fix for segfault with unknown exthdr
authorPhil Sutter <phil@nwl.cc>
Wed, 17 Mar 2021 19:39:38 +0000 (20:39 +0100)
committerPhil Sutter <phil@nwl.cc>
Tue, 30 Nov 2021 13:57:46 +0000 (14:57 +0100)
Unknown exthdr type with NFT_EXTHDR_F_PRESENT flag set caused
NULL-pointer deref. Fix this by moving the conditional exthdr.desc deref
atop the function and use the result in all cases.

Fixes: e02bd59c4009b ("exthdr: Implement existence check")
Signed-off-by: Phil Sutter <phil@nwl.cc>
src/exthdr.c

index 00d338f07302b59fef06ced47c5019f8dcd45426..c02b17d31754b834c392e97c3c0a13695eb45e58 100644 (file)
@@ -46,6 +46,9 @@ static const struct exthdr_desc *exthdr_find_desc(enum exthdr_desc_id desc_id)
 
 static void exthdr_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
+       const char *name = expr->exthdr.desc ?
+               expr->exthdr.desc->name : "unknown-exthdr";
+
        if (expr->exthdr.op == NFT_EXTHDR_OP_TCPOPT) {
                /* Offset calculation is a bit hacky at this point.
                 * There might be a tcp option one day with another
@@ -65,14 +68,14 @@ static void exthdr_expr_print(const struct expr *expr, struct output_ctx *octx)
                        return;
                }
 
-               nft_print(octx, "tcp option %s", expr->exthdr.desc->name);
+               nft_print(octx, "tcp option %s", name);
                if (expr->exthdr.flags & NFT_EXTHDR_F_PRESENT)
                        return;
                if (offset)
                        nft_print(octx, "%d", offset);
                nft_print(octx, " %s", expr->exthdr.tmpl->token);
        } else if (expr->exthdr.op == NFT_EXTHDR_OP_IPV4) {
-               nft_print(octx, "ip option %s", expr->exthdr.desc->name);
+               nft_print(octx, "ip option %s", name);
                if (expr->exthdr.flags & NFT_EXTHDR_F_PRESENT)
                        return;
                nft_print(octx, " %s", expr->exthdr.tmpl->token);
@@ -83,10 +86,9 @@ static void exthdr_expr_print(const struct expr *expr, struct output_ctx *octx)
                nft_print(octx, " %s", expr->exthdr.tmpl->token);
        } else {
                if (expr->exthdr.flags & NFT_EXTHDR_F_PRESENT)
-                       nft_print(octx, "exthdr %s", expr->exthdr.desc->name);
+                       nft_print(octx, "exthdr %s", name);
                else {
-                       nft_print(octx, "%s %s",
-                                 expr->exthdr.desc ? expr->exthdr.desc->name : "unknown-exthdr",
+                       nft_print(octx, "%s %s", name,
                                  expr->exthdr.tmpl->token);
                }
        }