]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
segtree: Fix range_mask_len() for subnet ranges exceeding unsigned int
authorStefano Brivio <sbrivio@redhat.com>
Wed, 5 May 2021 22:23:13 +0000 (00:23 +0200)
committerFlorian Westphal <fw@strlen.de>
Sat, 8 May 2021 14:58:50 +0000 (16:58 +0200)
As concatenated ranges are fetched from kernel sets and displayed to
the user, range_mask_len() evaluates whether the range is suitable for
display as netmask, and in that case it calculates the mask length by
right-shifting the endpoints until no set bits are left, but in the
existing version the temporary copies of the endpoints are derived by
copying their unsigned int representation, which doesn't suffice for
IPv6 netmask lengths, in general.

PetrB reports that, after inserting a /56 subnet in a concatenated set
element, it's listed as a /64 range. In fact, this happens for any
IPv6 mask shorter than 64 bits.

Fix this issue by simply sourcing the range endpoints provided by the
caller and setting the temporary copies with mpz_init_set(), instead
of fetching the unsigned int representation. The issue only affects
displaying of the masks, setting elements already works as expected.

Reported-by: PetrB <petr.boltik@gmail.com>
Bugzilla: https://bugzilla.netfilter.org/show_bug.cgi?id=1520
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
src/segtree.c

index ad199355532e0f0bc3cb3b59de3d95a87bb4cd2c..353a0053ebc05901a43ec5de519c96acde97f705 100644 (file)
@@ -838,8 +838,8 @@ static int range_mask_len(const mpz_t start, const mpz_t end, unsigned int len)
        mpz_t tmp_start, tmp_end;
        int ret;
 
-       mpz_init_set_ui(tmp_start, mpz_get_ui(start));
-       mpz_init_set_ui(tmp_end, mpz_get_ui(end));
+       mpz_init_set(tmp_start, start);
+       mpz_init_set(tmp_end, end);
 
        while (mpz_cmp(tmp_start, tmp_end) <= 0 &&
                !mpz_tstbit(tmp_start, 0) && mpz_tstbit(tmp_end, 0) &&