* [PATCH net] ipvs: prevent LBLCR destination leak after entry expiry
@ 2026-09-29 17:07 tjdqudcks0424
2026-09-30 7:44 ` Pablo Neira Ayuso
2026-09-30 15:38 ` Julian Anastasov
0 siblings, 2 replies; 3+ messages in thread
From: tjdqudcks0424 @ 2026-09-29 17:07 UTC (permalink / raw)
To: horms, ja
Cc: pablo, netdev, lvs-devel, netfilter-devel,
성병찬, stable
From: 성병찬 <tjdqudcks0424@naver.com>
ip_vs_lblcr_schedule() looks up a cache entry under RCU before taking
svc->sched_lock. The expiry timer can remove that entry from the hash
table and erase its destination set before the scheduler takes the lock.
RCU keeps the stale entry itself alive, so the scheduler can continue and
insert a new destination-set element into it. Since the entry is already
unhashed and its set was already erased, no later path finds the new
element. Both the element and its destination reference are leaked when
the parent entry is freed.
Recheck the address mapping while holding svc->sched_lock and update the
set only when the hash table still maps the address to the entry obtained
by the scheduler.
This was found during an AI-assisted source audit. Diagnostic-only timing
instrumentation forced expiry after lookup on a two-vCPU x86-64 QEMU
guest. The unmodified code inserted into the stale entry and left one
element outstanding in each of three runs; kmemleak reported the related
allocation in one run. With this change, the same stale-entry condition
was reached in three runs, but no stale insertion or outstanding element
remained.
An unforced 679-second run processed 65,536 marked packets without hitting
the race. The result therefore confirms the lifetime leak and the effect
of the fix under forced timing, but does not establish practical remote
resource exhaustion.
Fixes: c5549571f975 ("ipvs: convert lblcr scheduler to rcu")
Cc: stable@vger.kernel.org
Signed-off-by: 성병찬 <tjdqudcks0424@naver.com>
---
net/netfilter/ipvs/ip_vs_lblcr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index f53f05ceea36..ef18f3c9d5da 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -686,7 +686,8 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
/* Update our cache entry */
spin_lock_bh(&svc->sched_lock);
- if (!tbl->dead)
+ if (!tbl->dead &&
+ ip_vs_lblcr_get(svc->af, tbl, &iph->daddr) == en)
ip_vs_dest_set_insert(&en->set, dest, true);
spin_unlock_bh(&svc->sched_lock);
goto out;
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net] ipvs: prevent LBLCR destination leak after entry expiry
2026-09-29 17:07 [PATCH net] ipvs: prevent LBLCR destination leak after entry expiry tjdqudcks0424
@ 2026-09-30 7:44 ` Pablo Neira Ayuso
2026-09-30 15:38 ` Julian Anastasov
1 sibling, 0 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2026-09-30 7:44 UTC (permalink / raw)
To: tjdqudcks0424; +Cc: horms, ja, netdev, lvs-devel, netfilter-devel, stable
Please, stop posting fixes for patches that already exist.
If you want to use a LLM to fix bugs that's great, but you have to
track what is going on the mailing list already.
Thank you.
On Wed, Sep 30, 2026 at 02:07:46AM +0900, tjdqudcks0424@naver.com wrote:
> From: 성병찬 <tjdqudcks0424@naver.com>
>
> ip_vs_lblcr_schedule() looks up a cache entry under RCU before taking
> svc->sched_lock. The expiry timer can remove that entry from the hash
> table and erase its destination set before the scheduler takes the lock.
>
> RCU keeps the stale entry itself alive, so the scheduler can continue and
> insert a new destination-set element into it. Since the entry is already
> unhashed and its set was already erased, no later path finds the new
> element. Both the element and its destination reference are leaked when
> the parent entry is freed.
>
> Recheck the address mapping while holding svc->sched_lock and update the
> set only when the hash table still maps the address to the entry obtained
> by the scheduler.
>
> This was found during an AI-assisted source audit. Diagnostic-only timing
> instrumentation forced expiry after lookup on a two-vCPU x86-64 QEMU
> guest. The unmodified code inserted into the stale entry and left one
> element outstanding in each of three runs; kmemleak reported the related
> allocation in one run. With this change, the same stale-entry condition
> was reached in three runs, but no stale insertion or outstanding element
> remained.
>
> An unforced 679-second run processed 65,536 marked packets without hitting
> the race. The result therefore confirms the lifetime leak and the effect
> of the fix under forced timing, but does not establish practical remote
> resource exhaustion.
>
> Fixes: c5549571f975 ("ipvs: convert lblcr scheduler to rcu")
> Cc: stable@vger.kernel.org
> Signed-off-by: 성병찬 <tjdqudcks0424@naver.com>
> ---
> net/netfilter/ipvs/ip_vs_lblcr.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
> index f53f05ceea36..ef18f3c9d5da 100644
> --- a/net/netfilter/ipvs/ip_vs_lblcr.c
> +++ b/net/netfilter/ipvs/ip_vs_lblcr.c
> @@ -686,7 +686,8 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
>
> /* Update our cache entry */
> spin_lock_bh(&svc->sched_lock);
> - if (!tbl->dead)
> + if (!tbl->dead &&
> + ip_vs_lblcr_get(svc->af, tbl, &iph->daddr) == en)
> ip_vs_dest_set_insert(&en->set, dest, true);
> spin_unlock_bh(&svc->sched_lock);
> goto out;
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net] ipvs: prevent LBLCR destination leak after entry expiry
2026-09-29 17:07 [PATCH net] ipvs: prevent LBLCR destination leak after entry expiry tjdqudcks0424
2026-09-30 7:44 ` Pablo Neira Ayuso
@ 2026-09-30 15:38 ` Julian Anastasov
1 sibling, 0 replies; 3+ messages in thread
From: Julian Anastasov @ 2026-09-30 15:38 UTC (permalink / raw)
To: 성병찬
Cc: horms, pablo, netdev, lvs-devel, netfilter-devel, stable
[-- Attachment #1: Type: text/plain, Size: 2714 bytes --]
Hello,
On Wed, 30 Sep 2026, tjdqudcks0424@naver.com wrote:
> From: 성병찬 <tjdqudcks0424@naver.com>
>
> ip_vs_lblcr_schedule() looks up a cache entry under RCU before taking
> svc->sched_lock. The expiry timer can remove that entry from the hash
> table and erase its destination set before the scheduler takes the lock.
>
> RCU keeps the stale entry itself alive, so the scheduler can continue and
> insert a new destination-set element into it. Since the entry is already
> unhashed and its set was already erased, no later path finds the new
> element. Both the element and its destination reference are leaked when
> the parent entry is freed.
>
> Recheck the address mapping while holding svc->sched_lock and update the
> set only when the hash table still maps the address to the entry obtained
> by the scheduler.
>
> This was found during an AI-assisted source audit. Diagnostic-only timing
> instrumentation forced expiry after lookup on a two-vCPU x86-64 QEMU
> guest. The unmodified code inserted into the stale entry and left one
> element outstanding in each of three runs; kmemleak reported the related
> allocation in one run. With this change, the same stale-entry condition
> was reached in three runs, but no stale insertion or outstanding element
> remained.
>
> An unforced 679-second run processed 65,536 marked packets without hitting
> the race. The result therefore confirms the lifetime leak and the effect
> of the fix under forced timing, but does not establish practical remote
> resource exhaustion.
>
> Fixes: c5549571f975 ("ipvs: convert lblcr scheduler to rcu")
> Cc: stable@vger.kernel.org
> Signed-off-by: 성병찬 <tjdqudcks0424@naver.com>
> ---
> net/netfilter/ipvs/ip_vs_lblcr.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
> index f53f05ceea36..ef18f3c9d5da 100644
> --- a/net/netfilter/ipvs/ip_vs_lblcr.c
> +++ b/net/netfilter/ipvs/ip_vs_lblcr.c
> @@ -686,7 +686,8 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
>
> /* Update our cache entry */
> spin_lock_bh(&svc->sched_lock);
> - if (!tbl->dead)
> + if (!tbl->dead &&
> + ip_vs_lblcr_get(svc->af, tbl, &iph->daddr) == en)
ip_vs_dest_set_eraseall() does not update set->size, what if
we use atomic_set(&set->size, -1) there and to check it here to
avoid inserting dest into dying en? This should reduce the time
while we hold sched_lock.
if (!tbl->dead && atomic_read(&en->set.size) >= 0)
> ip_vs_dest_set_insert(&en->set, dest, true);
> spin_unlock_bh(&svc->sched_lock);
> goto out;
> --
> 2.43.0
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-30 15:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 17:07 [PATCH net] ipvs: prevent LBLCR destination leak after entry expiry tjdqudcks0424
2026-09-30 7:44 ` Pablo Neira Ayuso
2026-09-30 15:38 ` Julian Anastasov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox