pf: fix another endpoint-independent crash

In c12013f5bb we fixed udp_mapping cleanup issues in pf_get_sport(), but
missed the static-port case (i.e. low == 0 && high == 0). We could still exit
pf_get_sport() without either inserting the udp_mapping or freeing it.

Address this and add a test case to provoke the problem.

Reviewed by:	thj
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D53856
This commit is contained in:
Kristof Provost
2025-11-21 10:03:36 +01:00
parent d8bfcacd12
commit 7dedc3c214
2 changed files with 42 additions and 4 deletions
+12 -4
View File
@@ -407,10 +407,18 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr,
*/
key.port[sidx] = pd->nsport;
if (!pf_find_state_all_exists(&key, dir)) {
MPASS(udp_mapping == NULL ||
*udp_mapping == NULL);
*nport = pd->nsport;
return (0);
if (udp_mapping && *udp_mapping != NULL) {
(*udp_mapping)->endpoints[1].port = pd->nsport;
if (pf_udp_mapping_insert(*udp_mapping) == 0) {
*nport = pd->nsport;
return (0);
}
} else {
MPASS(udp_mapping == NULL ||
*udp_mapping == NULL);
*nport = pd->nsport;
return (0);
}
}
} else if (low == high) {
key.port[sidx] = htons(low);
+30
View File
@@ -289,6 +289,35 @@ endpoint_independent_exhaust_cleanup()
rm -f server2.out
}
atf_test_case "endpoint_independent_static_port" "cleanup"
endpoint_independent_static_port_head()
{
atf_set descr 'Test that a client behind NAT gets the same external IP:port for different servers, with static-port'
atf_set require.user root
}
endpoint_independent_static_port_body()
{
endpoint_independent_setup # Sets ${epair_…} variables
endpoint_independent_common \
"nat on ${epair_nat}a inet from ! (${epair_nat}a) to any -> (${epair_nat}a)" \
"nat on ${epair_nat}a inet from ! (${epair_nat}a) to any -> (${epair_nat}a) static-port sticky-address endpoint-independent"
# Exhaust the available nat ports
for i in $(seq 1 10); do
echo "ping" | jexec client nc -u 198.51.100.32 1234 -w 0
echo "ping" | jexec client nc -u 198.51.100.22 1234 -w 0
done
}
endpoint_independent_static_port_cleanup()
{
pft_cleanup
rm -f server1.out
rm -f server2.out
}
atf_test_case "endpoint_independent_pass" "cleanup"
endpoint_independent_pass_head()
{
@@ -930,6 +959,7 @@ atf_init_test_cases()
atf_add_test_case "nested_anchor"
atf_add_test_case "endpoint_independent_compat"
atf_add_test_case "endpoint_independent_exhaust"
atf_add_test_case "endpoint_independent_static_port"
atf_add_test_case "endpoint_independent_pass"
atf_add_test_case "nat6_nolinklocal"
atf_add_test_case "empty_table_source_hash"