@@ -845,6 +845,7 @@ static void ip_vs_proc_conn(struct netns_ipvs *ipvs, struct ip_vs_conn_param *pa
unsigned long timeout, __u32 fwmark,
struct ip_vs_sync_conn_options *opt)
{
+ struct ip_vs_conn *cp_new = NULL;
struct ip_vs_dest *dest;
struct ip_vs_conn *cp;
@@ -886,9 +887,6 @@ static void ip_vs_proc_conn(struct netns_ipvs *ipvs, struct ip_vs_conn_param *pa
flags &= IP_VS_CONN_F_BACKUP_UPD_MASK;
flags |= cp->flags & ~IP_VS_CONN_F_BACKUP_UPD_MASK;
cp->flags = flags;
- spin_unlock_bh(&cp->lock);
- if (!dest)
- ip_vs_try_bind_dest(cp);
} else {
/*
* Find the appropriate destination for the connection.
@@ -915,6 +913,8 @@ static void ip_vs_proc_conn(struct netns_ipvs *ipvs, struct ip_vs_conn_param *pa
}
if (!(flags & IP_VS_CONN_F_TEMPLATE))
kfree(param->pe_data);
+ cp_new = cp;
+ spin_lock_bh(&cp->lock);
}
if (opt) {
@@ -946,6 +946,9 @@ static void ip_vs_proc_conn(struct netns_ipvs *ipvs, struct ip_vs_conn_param *pa
else
cp->timeout = (3*60*HZ);
}
+ spin_unlock_bh(&cp->lock);
+ if (!dest && !cp_new)
+ ip_vs_try_bind_dest(cp);
ip_vs_conn_put(cp);
}
Sashiko reports that we modify the conn flags and seq values in the backup server without holding cp->lock. The same is true for other fields such as state, old_state and timeout which are modified by protocols under lock. Extend the locked region in ip_vs_proc_conn() to update the fields atomically. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260927220816.268206-1-pablo%40netfilter.org Signed-off-by: Julian Anastasov <ja@ssi.bg> --- net/netfilter/ipvs/ip_vs_sync.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)