Currently, inet_peer_threshold is used to trigger aggressive garbage collection when tree size reaches the threshold. However, if garbage collection is unable to reclaim candidate entries (e.g. due to held references or active fragment queues), base->total can grow without any upper bound, consuming excessive slab memory. Fix this by enforcing a hard limit on inet_peer allocations when (u64)base->total reaches 2ULL * READ_ONCE(inet_peer_threshold). Casting to 64-bit unsigned avoids signed integer overflow if inet_peer_threshold is configured to large values via sysctl. Additionally, when peer allocation fails and returns NULL, inet_peer_xrlim_allow() previously returned true, allowing packets without rate limiting. Fix this to return false when peer is NULL, ensuring rate limiting fails closed under memory pressure. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Michael Blunt Signed-off-by: Eric Dumazet --- net/ipv4/inetpeer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 5b957a831e7c39f2e9b224469f0eba4703833475..1e2bd1c522326c9ba14c3ceeb8e934f703b827a5 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -192,7 +192,8 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base, gc_cnt = 0; p = lookup(daddr, base, seq, gc_stack, &gc_cnt, &parent, &pp); if (!p) { - p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC); + if ((u64)base->total < 2ULL * READ_ONCE(inet_peer_threshold)) + p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC); if (p) { p->daddr = *daddr; p->dtime = (__u32)jiffies; @@ -248,7 +249,7 @@ bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout) bool rc = false; if (!peer) - return true; + return false; token = otoken = READ_ONCE(peer->rate_tokens); now = jiffies; -- 2.55.0.691.gc56d675ccc-goog