From: Timo Sirainen Date: Fri, 20 Jan 2023 15:43:55 +0000 (+0200) Subject: lib: net_is_in_network() - Fix checking scope ID in IPv6 X-Git-Tag: 2.4.0~3097 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ffff307885d2dd15b91c3fe2b13d667a0cfd7a0;p=thirdparty%2Fdovecot%2Fcore.git lib: net_is_in_network() - Fix checking scope ID in IPv6 Using "ip%iface1" shouldn't match "ip%iface2". However, do allow it to match "ip" when %iface is missing. --- diff --git a/src/lib/net.c b/src/lib/net.c index b101b45ce0..326cebe099 100644 --- a/src/lib/net.c +++ b/src/lib/net.c @@ -1228,6 +1228,12 @@ bool net_is_in_network(const struct ip_addr *ip, } else { ip1 = (const void *)&ip->u.ip6; ip2 = (const void *)&net_ip->u.ip6; + if (ip->scope_id != net_ip->scope_id && + net_ip->scope_id != 0) { + /* %iface1 != %iface2 never matches, but allow + missing interface on the net_ip */ + return FALSE; + } } /* check first the full 32bit ints */ diff --git a/src/lib/test-net.c b/src/lib/test-net.c index f703a983e9..19887d830b 100644 --- a/src/lib/test-net.c +++ b/src/lib/test-net.c @@ -32,6 +32,7 @@ static void test_net_is_in_network(void) { "::ffff:1.2.3.4", "1.2.3.4", 32, TRUE }, { "::ffff:1.2.3.4", "1.2.3.3", 32, FALSE }, { "::ffff:1.2.3.4", "::ffff:1.2.3.4", 0, FALSE }, + { "fe80::1%lo", "fe80::%lo", 8, TRUE }, { "fe80::1%lo", "fe80::", 8, TRUE }, }; struct ip_addr ip, net_ip; @@ -55,6 +56,13 @@ static void test_net_is_in_network(void) net_ip.family = 0; test_assert(!net_is_in_network(&ip, &net_ip, 0)); test_assert(!net_is_in_network(&net_ip, &ip, 0)); + + /* make sure a changed scope_id won't match */ + test_assert(net_addr2ip("fe80::1%lo", &ip) == 0); + test_assert(net_addr2ip("fe80::1%lo", &net_ip) == 0); + test_assert(net_is_in_network(&ip, &net_ip, 1)); + net_ip.scope_id++; + test_assert(!net_is_in_network(&ip, &net_ip, 1)); test_end(); }