mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
ipvs: do not leak dest after get from dest trash
Sashiko warns about leaked dest if ip_vs_start_estimator()
fails in ip_vs_add_dest(). Add ip_vs_trash_put_dest() to
put back the dest into dest trash.
Link: https://sashiko.dev/#/patchset/20260428175725.72050-1-ja%40ssi.bg
Fixes: 705dd34440 ("ipvs: use kthreads for stats estimation")
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
d493d9de1c
commit
fbe1e01e81
|
|
@ -1102,6 +1102,24 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, int dest_af,
|
|||
return dest;
|
||||
}
|
||||
|
||||
/* Put destination in trash */
|
||||
static void ip_vs_trash_put_dest(struct netns_ipvs *ipvs,
|
||||
struct ip_vs_dest *dest, unsigned long istart,
|
||||
bool cleanup)
|
||||
{
|
||||
spin_lock_bh(&ipvs->dest_trash_lock);
|
||||
IP_VS_DBG_BUF(3, "Moving dest %s:%u into trash, dest->refcnt=%d\n",
|
||||
IP_VS_DBG_ADDR(dest->af, &dest->addr), ntohs(dest->port),
|
||||
refcount_read(&dest->refcnt));
|
||||
if (list_empty(&ipvs->dest_trash) && !cleanup)
|
||||
mod_timer(&ipvs->dest_trash_timer,
|
||||
jiffies + (IP_VS_DEST_TRASH_PERIOD >> 1));
|
||||
/* dest lives in trash with reference */
|
||||
list_add(&dest->t_list, &ipvs->dest_trash);
|
||||
dest->idle_start = istart;
|
||||
spin_unlock_bh(&ipvs->dest_trash_lock);
|
||||
}
|
||||
|
||||
static void ip_vs_dest_rcu_free(struct rcu_head *head)
|
||||
{
|
||||
struct ip_vs_dest *dest;
|
||||
|
|
@ -1461,9 +1479,12 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
|
|||
ntohs(dest->vport));
|
||||
|
||||
ret = ip_vs_start_estimator(svc->ipvs, &dest->stats);
|
||||
/* On error put back dest into the trash */
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
__ip_vs_update_dest(svc, dest, udest, 1);
|
||||
ip_vs_trash_put_dest(svc->ipvs, dest, dest->idle_start,
|
||||
false);
|
||||
else
|
||||
__ip_vs_update_dest(svc, dest, udest, 1);
|
||||
} else {
|
||||
/*
|
||||
* Allocate and initialize the dest structure
|
||||
|
|
@ -1533,17 +1554,7 @@ static void __ip_vs_del_dest(struct netns_ipvs *ipvs, struct ip_vs_dest *dest,
|
|||
*/
|
||||
ip_vs_rs_unhash(dest);
|
||||
|
||||
spin_lock_bh(&ipvs->dest_trash_lock);
|
||||
IP_VS_DBG_BUF(3, "Moving dest %s:%u into trash, dest->refcnt=%d\n",
|
||||
IP_VS_DBG_ADDR(dest->af, &dest->addr), ntohs(dest->port),
|
||||
refcount_read(&dest->refcnt));
|
||||
if (list_empty(&ipvs->dest_trash) && !cleanup)
|
||||
mod_timer(&ipvs->dest_trash_timer,
|
||||
jiffies + (IP_VS_DEST_TRASH_PERIOD >> 1));
|
||||
/* dest lives in trash with reference */
|
||||
list_add(&dest->t_list, &ipvs->dest_trash);
|
||||
dest->idle_start = 0;
|
||||
spin_unlock_bh(&ipvs->dest_trash_lock);
|
||||
ip_vs_trash_put_dest(ipvs, dest, 0, cleanup);
|
||||
|
||||
/* Queue up delayed work to expire all no destination connections.
|
||||
* No-op when CONFIG_SYSCTL is disabled.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user