linux/net/netfilter/ipvs
Julian Anastasov 5522d65d81 ipvs: avoid possible loop in ip_vs_dst_event on resizing
Sashiko points out that unprivileged user can frequently
call ip_vs_flush() or ip_vs_del_service() to trigger
svc_table_changes updates that can lead to infinite loop
in ip_vs_dst_event(). This can also happen if the user
triggers frequent table resizing without deleting all
services. We should also consider the possible effects
if the user triggers many NETDEV_DOWN events.

One way to solve it is to hold svc_resize_sem in
ip_vs_dst_event() but this can block the dev notifier
during the whole resizing process.

Instead, use new rw_semaphore svc_replace_sem to protect just
the svc_table replacement which is a short code section.
Then hold svc_replace_sem in ip_vs_dst_event() to serialize
with replacing the svc_table. As result, loop is avoided
as there is no need to repeat the table walking from the
start. By this way changes in svc_table_changes can happen
only when all services are removed and all dev references
dropped which allows us to abort the table walking.

As IP_VS_WORK_SVC_NORESIZE is the flag used to stop the
svc_resize_work under service_mutex, we should check only
this flag often but not while under service_mutex.

To remove the mutex_trylock() for service_mutex in the
second phase where the resizer installs the new table
after rehashing, we will avoid holding the service_mutex
there. As result, the code in configuration context which
is under service_mutex should access ipvs->svc_table under
RCU because it can be replaced at anytime and released
after a RCU grace period. As for ip_vs_zero_all(), it needs
different solution as a table walker which can escape
single RCU read-side critical section: to hold the
svc_replace_sem to prevent table to be replaced.

In ip_vs_status_show() prefer to hold svc_replace_sem
to avoid many loops, just detect if the svc_table is
removed.

Prefer the newly attached table for the u_thresh/l_thresh
checks to know when to grow/shrink while adding or deleting
services because the new table size is based on the latest
parameters.

Link: https://sashiko.dev/#/patchset/20260505001648.360569-1-pablo%40netfilter.org
Fixes: 840aac3d90 ("ipvs: use resizable hash table for services")
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
History 2026-05-16 12:19:56 +02:00
..
ip_vs_app.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_conn.c ipvs: fix the spin_lock usage for RT build 2026-05-05 01:52:55 +02:00
ip_vs_core.c ipvs: fix shift-out-of-bounds in ip_vs_rht_desired_size 2026-05-05 01:52:55 +02:00
ip_vs_ctl.c ipvs: avoid possible loop in ip_vs_dst_event on resizing 2026-05-16 12:19:56 +02:00
ip_vs_dh.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ip_vs_est.c ipvs: fix races around est_mutex and est_cpulist 2026-05-05 01:52:55 +02:00
ip_vs_fo.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_ftp.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_lblc.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ip_vs_lblcr.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ip_vs_lc.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_mh.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
ip_vs_nfct.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_nq.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_ovf.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_pe.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_pe_sip.c ipvs: switch to per-net connection table 2026-03-04 11:45:45 +01:00
ip_vs_proto.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ip_vs_proto_ah_esp.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_proto_sctp.c ipvs: skip ipv6 extension headers for csum checks 2026-02-17 15:04:20 +01:00
ip_vs_proto_tcp.c ipvs: skip ipv6 extension headers for csum checks 2026-02-17 15:04:20 +01:00
ip_vs_proto_udp.c ipvs: skip ipv6 extension headers for csum checks 2026-02-17 15:04:20 +01:00
ip_vs_rr.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_sched.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_sed.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_sh.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ip_vs_sync.c ipvs: switch to per-net connection table 2026-03-04 11:45:45 +01:00
ip_vs_twos.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_wlc.c net: Remove KMSG_COMPONENT macro 2025-11-28 19:20:27 -08:00
ip_vs_wrr.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ip_vs_xmit.c ipvs: fix MTU check for GSO packets in tunnel mode 2026-04-20 23:45:43 +02:00
Kconfig sctp: use skb_crc32c() instead of __skb_checksum() 2025-05-21 15:40:16 -07:00
Makefile ipvs: add weighted random twos choice algorithm 2021-01-26 01:09:46 +01:00