IPVS estimator kthread 0 starts with zeroed chain and tick limits until its initial calculation phase completes. If network namespace teardown clears ipvs->enable during that phase, ip_vs_est_calc_phase() can return without installing positive limits. The kthread can then continue into its main loop and drain est_temp_list with zero chain_max, tick_max and est_max_count values. Each enqueue consumes one available tick row, but est_count never reaches the zero est_max_count value. After all rows are consumed, the row lookup returns IPVS_EST_NTICKS and ip_vs_enqueue_estimator() writes past the ticks and tick_len arrays. Exit kthread 0 after the calculation phase if the kthread is stopping or IPVS has been disabled. That keeps temporary estimators from being drained after the limits failed to initialize. Fixes: 705dd3444081 ("ipvs: use kthreads for stats estimation") Cc: stable@vger.kernel.org Reported-by: Vega Signed-off-by: Zhiling Zou --- changes in v2: - Exit the estimator kthread after the calculation phase if IPVS has been disabled or the kthread is stopping, as suggested by Julian Anastasov. - Drop the later enqueue and drain guards from v1. - v1 Link: https://lore.kernel.org/all/6359e0031f0ee7cc969bae3483308de362d3c709.1784878022.git.zhilinz@nebusec.ai net/netfilter/ipvs/ip_vs_est.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c index ab09f51829512..86d20f19fe317 100644 --- a/net/netfilter/ipvs/ip_vs_est.c +++ b/net/netfilter/ipvs/ip_vs_est.c @@ -191,8 +191,11 @@ static int ip_vs_estimation_kthread(void *data) } /* kthread 0 will handle the calc phase */ - if (ipvs->est_calc_phase) + if (ipvs->est_calc_phase) { ip_vs_est_calc_phase(ipvs); + if (kthread_should_stop() || !READ_ONCE(ipvs->enable)) + return 0; + } } while (1) { -- 2.43.0