]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
nft: Increase rule parser strictness
authorPhil Sutter <phil@nwl.cc>
Thu, 15 Dec 2022 14:08:01 +0000 (15:08 +0100)
committerPhil Sutter <phil@nwl.cc>
Tue, 20 Dec 2022 20:49:38 +0000 (21:49 +0100)
Catch more unexpected conditions.

Signed-off-by: Phil Sutter <phil@nwl.cc>
iptables/nft-arp.c
iptables/nft-bridge.c
iptables/nft-ipv4.c
iptables/nft-ipv6.c
iptables/nft-shared.c

index edf179521e35544c951ab4f91e9ff030bc9b5840..210f43d2cefbe3fa4119ff71c8cf76dd19cbb095 100644 (file)
@@ -288,6 +288,8 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
 
                        if (inv)
                                fw->arp.invflags |= IPT_INV_DSTIP;
+               } else {
+                       ctx->errmsg = "unknown payload offset";
                }
                break;
        }
index e223d19765f90a054c73eacd983aa40550c80478..83cbe31559d4b3216b2b6e6c9edb562eee0c5ff7 100644 (file)
@@ -287,6 +287,10 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
                        fw->invflags |= EBT_IPROTO;
                fw->bitmask &= ~EBT_NOPROTO;
                break;
+       default:
+               DEBUGP("unknown payload offset %d\n", reg->payload.offset);
+               ctx->errmsg = "unknown payload offset";
+               break;
        }
 }
 
index 42167351710e6af658872c1e5a7eb5313c01a08a..dcc4a8edfc87ff66024217920da186e49e30eec4 100644 (file)
@@ -207,10 +207,12 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx,
                        cs->fw.ip.invflags |= IPT_INV_FRAG;
                break;
        case offsetof(struct iphdr, ttl):
-               nft_parse_hl(ctx, e, cs);
+               if (nft_parse_hl(ctx, e, cs) < 0)
+                       ctx->errmsg = "invalid ttl field match";
                break;
        default:
                DEBUGP("unknown payload offset %d\n", sreg->payload.offset);
+               ctx->errmsg = "unknown payload offset";
                break;
        }
 }
index 3a373b7eb2cfe23872b8a111a0108ebc0b8616df..e98921856c75d43ec1a6c4c7af8ff9ab3dc772be 100644 (file)
@@ -173,10 +173,12 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx,
                if (inv)
                        cs->fw6.ipv6.invflags |= IP6T_INV_PROTO;
        case offsetof(struct ip6_hdr, ip6_hlim):
-               nft_parse_hl(ctx, e, cs);
+               if (nft_parse_hl(ctx, e, cs) < 0)
+                       ctx->errmsg = "invalid ttl field match";
                break;
        default:
                DEBUGP("unknown payload offset %d\n", reg->payload.offset);
+               ctx->errmsg = "unknown payload offset";
                break;
        }
 }
index d4b21921077d94d8a8ebedd1e86175df6ab164c6..c13fc307e7a89b324ebc89f3c37a997258a460a0 100644 (file)
@@ -444,8 +444,10 @@ static void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
        size_t size;
 
        target = xtables_find_target(targname, XTF_TRY_LOAD);
-       if (target == NULL)
+       if (target == NULL) {
+               ctx->errmsg = "target extension not found";
                return;
+       }
 
        size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len;
 
@@ -482,8 +484,10 @@ static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
        }
 
        match = xtables_find_match(mt_name, XTF_TRY_LOAD, matches);
-       if (match == NULL)
+       if (match == NULL) {
+               ctx->errmsg = "match extension not found";
                return;
+       }
 
        m = xtables_calloc(1, sizeof(struct xt_entry_match) + mt_len);
        memcpy(&m->data, mt_info, mt_len);
@@ -690,9 +694,10 @@ static struct xt_tcp *nft_tcp_match(struct nft_xt_ctx *ctx,
 
        if (!tcp) {
                match = nft_create_match(ctx, cs, "tcp");
-               if (!match)
+               if (!match) {
+                       ctx->errmsg = "tcp match extension not found";
                        return NULL;
-
+               }
                tcp = (void*)match->m->data;
                ctx->tcpudp.tcp = tcp;
        }
@@ -904,6 +909,8 @@ static void nft_parse_th_port(struct nft_xt_ctx *ctx,
        case IPPROTO_TCP:
                nft_parse_tcp(ctx, cs, sport, dport, op);
                break;
+       default:
+               ctx->errmsg = "unknown layer 4 protocol for TH match";
        }
 }
 
@@ -957,8 +964,8 @@ static void nft_parse_transport(struct nft_xt_ctx *ctx,
                proto = ctx->cs->fw6.ipv6.proto;
                break;
        default:
-               proto = 0;
-               break;
+               ctx->errmsg = "invalid family for TH match";
+               return;
        }
 
        nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
@@ -1129,8 +1136,10 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
                if (!dreg)
                        return;
 
-               if (len > sizeof(dreg->immediate.data))
+               if (len > sizeof(dreg->immediate.data)) {
+                       ctx->errmsg = "oversized immediate data";
                        return;
+               }
 
                memcpy(dreg->immediate.data, imm_data, len);
                dreg->immediate.len = len;
@@ -1163,8 +1172,10 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
        }
 
        cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
-       if (!cs->target)
+       if (!cs->target) {
+               ctx->errmsg = "verdict extension not found";
                return;
+       }
 
        size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
        t = xtables_calloc(1, size);
@@ -1197,8 +1208,10 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
        }
 
        match = xtables_find_match("limit", XTF_TRY_LOAD, matches);
-       if (match == NULL)
+       if (match == NULL) {
+               ctx->errmsg = "limit match extension not found";
                return;
+       }
 
        size = XT_ALIGN(sizeof(struct xt_entry_match)) + match->size;
        match->m = xtables_calloc(1, size);
@@ -1245,8 +1258,10 @@ static void nft_parse_log(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
                         nftnl_expr_get_str(e, NFTNL_EXPR_LOG_PREFIX));
 
        target = xtables_find_target("NFLOG", XTF_TRY_LOAD);
-       if (target == NULL)
+       if (target == NULL) {
+               ctx->errmsg = "NFLOG target extension not found";
                return;
+       }
 
        target_size = XT_ALIGN(sizeof(struct xt_entry_target)) +
                      XT_ALIGN(sizeof(struct xt_nflog_info_nft));