]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
segtree: broken error reporting with mappings
authorPablo Neira Ayuso <pablo@netfilter.org>
Sat, 11 Apr 2020 12:19:36 +0000 (14:19 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 11 Apr 2020 15:21:58 +0000 (17:21 +0200)
Segfault on error reporting when intervals overlap.

ip saddr vmap {
    10.0.1.0-10.0.1.255 : accept,
    10.0.1.1-10.0.2.255 : drop
}

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1415
Fixes: 4d6ad0f310d6 ("segtree: check for overlapping elements at insertion")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/segtree.c
tests/py/inet/ip.t

index 8d79332d8578ee8328d5fea77f27d46ae08071c5..a9d6ecc89d7c17c5e4323d71ec45db80958d0449 100644 (file)
@@ -190,7 +190,8 @@ static bool segtree_debug(unsigned int debug_mask)
 static int ei_insert(struct list_head *msgs, struct seg_tree *tree,
                     struct elementary_interval *new, bool merge)
 {
-       struct elementary_interval *lei, *rei;
+       struct elementary_interval *lei, *rei, *ei;
+       struct expr *new_expr, *expr;
        mpz_t p;
 
        mpz_init2(p, tree->keylen);
@@ -205,8 +206,10 @@ static int ei_insert(struct list_head *msgs, struct seg_tree *tree,
                pr_gmp_debug("insert: [%Zx %Zx]\n", new->left, new->right);
 
        if (lei != NULL && rei != NULL && lei == rei) {
-               if (!merge)
+               if (!merge) {
+                       ei = lei;
                        goto err;
+               }
                /*
                 * The new interval is entirely contained in the same interval,
                 * split it into two parts:
@@ -228,8 +231,10 @@ static int ei_insert(struct list_head *msgs, struct seg_tree *tree,
                ei_destroy(lei);
        } else {
                if (lei != NULL) {
-                       if (!merge)
+                       if (!merge) {
+                               ei = lei;
                                goto err;
+                       }
                        /*
                         * Left endpoint is within lei, adjust it so we have:
                         *
@@ -248,8 +253,10 @@ static int ei_insert(struct list_head *msgs, struct seg_tree *tree,
                        }
                }
                if (rei != NULL) {
-                       if (!merge)
+                       if (!merge) {
+                               ei = rei;
                                goto err;
+                       }
                        /*
                         * Right endpoint is within rei, adjust it so we have:
                         *
@@ -276,7 +283,15 @@ static int ei_insert(struct list_head *msgs, struct seg_tree *tree,
        return 0;
 err:
        errno = EEXIST;
-       return expr_binary_error(msgs, lei->expr, new->expr,
+       if (new->expr->etype == EXPR_MAPPING) {
+               new_expr = new->expr->left;
+               expr = ei->expr->left;
+       } else {
+               new_expr = new->expr;
+               expr = ei->expr;
+       }
+
+       return expr_binary_error(msgs, new_expr, expr,
                                 "conflicting intervals specified");
 }
 
index 4eb69d7362e39a8c1a30a78f87fdcb4913a888ba..86604a6363dd264170b9e2486446f1059eb84ed0 100644 (file)
@@ -7,3 +7,5 @@
 *netdev;test-netdev;ingress
 
 ip saddr . ip daddr . ether saddr { 1.1.1.1 . 2.2.2.2 . ca:fe:ca:fe:ca:fe };ok
+ip saddr vmap { 10.0.1.0-10.0.1.255 : accept, 10.0.1.1-10.0.2.255 : drop };fail
+ip saddr vmap { 1.1.1.1-1.1.1.255 : accept, 1.1.1.0-1.1.2.1 : drop};fail