From nobody Fri Sep 25 03:16:14 2026 Received: from mail-pj2-f12.google.com (mail-pj2-f12.google.com [74.125.227.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55ABF393DDB for ; Thu, 17 Sep 2026 03:03:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.140 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789614191; cv=none; b=FnB+yBCCM/a8mn9Q4eA2nUusdozPSjU8pYaRsfBGXP5+VaglJGihpRdhhzCjc4u3S3j0GxyJsDHtUJiZ+lSg54ZV1OWpF15J/v6sTs9Q14RuUwdcCB2qqvXBy+2YdgK6Lr1FoJSaaFbB/IUhgeiAzW0sooy12iAMxyorsuQ1a+E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789614191; c=relaxed/simple; bh=m8LxNkR3JjYdnLQmQUxBOKzt4ZAa5DQI7wyelbxomQ8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SDCB5/LNj1p7Qw+3xKC1Q8ZO/7zLIjqKwPES1prlx6bzVhKrKS99RuAtpjxyF5xCBWGfODYiZi6+ox0jUeaszGjaWyT0gvtxIiJW0kr9xt7Si3J/GuIKXSNlbjERe6hC9HfiTAefGWtVQKjB+5sIWJ0GWb1DXIVI/dMHhmCIG5s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai; spf=pass smtp.mailfrom=nebusec.ai; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b=BviUxLKQ; arc=none smtp.client-ip=74.125.227.140 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b="BviUxLKQ" Received: by mail-pj2-f12.google.com with SMTP id d9443c01a7336-2d8fbef5018so3716275ad.0 for ; Wed, 16 Sep 2026 20:03:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nebusec.ai; s=google; t=1789614186; x=1790218986; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=86BxvtSGF7VvPfVtVAdcLjZ1htilmwcxvCG0+eDxXR4=; b=BviUxLKQ0vfBR9QOw/teSbzE4olf2QsV8zCK/tPkpZSIUdzl5O9Jjp9i8TyfDSiKn4 8djg2U3dXX/m9jLfEMrc90lzgYQy4cgI6ZK0PaZJRGhEG9LaDYpHZo7nBAnw7ZZaJyYB CgxIJdvPF1yZtdvDu7PdlLRtbVExK9wBq2DtOPBPLT2HazlmslWo7r4Pu21S8Sg2OHPY z7uOMV0aiDvNZizORjRzNNB8CdLQJULsCURtWeKRkcA5vjUpaKO4J7GYb+XYXq/h0ItR Q7TVi2+E15ja3MFxpXMD4OqpUWqUFJmqkHyNH/pM3IqNW08ZSrtMEUo60bIB/DMx7CXP O4pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789614186; x=1790218986; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=86BxvtSGF7VvPfVtVAdcLjZ1htilmwcxvCG0+eDxXR4=; b=ZNruNMqbfIfJ5gdcRGnmJky3vYGY+gdQnZ21Zu+k72+VMEru6tIYFUZChW3gX79VPa Rl82exPj24UOlfp2AW6C3kSlJqbSOED5Zp7ax7rt6nmxJstymqKcCktMDOgCsjd9bX+o 4YbKi8kBCkBQB0Bn1RkYcPkcNUqYypXt2WyJhzV9DZaGueHDy9O/tJh3cNhxGoDL7EoN zKbbpCvAcTT4wnPttVo/b1ysIIhu8F/YNnZ0ZusS+vk19RmNbWOp6yBWbJUvG9Qh840w BQQHXzEzOCfkVojDCy7WkheGOv5usJfzoMMwBbq53vN5vfOoR9mlbbdubqPal/0eJHw/ Mi9g== X-Forwarded-Encrypted: i=1; AKwUvBw/GndYn7Wp+5gpzsn6ZVGAXDNlHmScNxCgf024jvvXcCNv1MI6VNyE5/JKBJAsQKbSAHzAdb67vk5oxu0=@vger.kernel.org X-Gm-Message-State: AFuF++mJPcsPu41dwe7WiL96jg0thIdCZz3u/UXADQ8WBun1rNpI2O78 D5wVzMdEomivvfHTF8zYM2Izlwf343jkOgM8kh05KBrEY/xc8hiCRFO6eWWUzefmPk3o X-Gm-Gg: AYBFou0u2lfPbll28l/BClH26Q7W3PJPCBy6CA20nlELNPVzAoY6RGRSBjUdzV5uyri umr6TyeE/pWSf5fyN7i3DYHMQD/pNAOmvb/SRFkep35J46GTECzc08ifBI23o8s7mnwDsbloZQ1 CG3IbNfGdPOaahfYKH8n5dRKRLUuExtIbh+Z5ZmPkm7Co+CdGp7PaASvztYMSTSY6X+yYIl6brP 0HVNqaAQ0NHgGdd9YNYtGWsEifoNffS2Fq33H688znzpahUIqlSqBHOJg8gS82SUtvJmbrznLYs WY5CetmouaPWwlNU0huuKz+JSu60x+IHxESDNKjM2wM+NC4Yg6Z94aiTzE9SmdXPn4xx5qwxFd4 jLjNUdjhDYDRbh5vN2EJ2bSFFUItJDZvOXnu7Rfg324VlZJ5B/EPWj8OPcI3nwFqZvcDqsRQjd6 VPzkZiTm6ENGfjag2njpvJqYwSE1yjXKLtcalDvHtIt6xc6fsX4NceQBA1vibOsff8UHSc1AZcM GYtDFT0/6fdjK5cMvzRMzpdyAdp1cx5i0M4VIzG X-Received: by 2002:a17:903:19cc:b0:2bf:dd0:c8b1 with SMTP id d9443c01a7336-2dd8cc71b12mr120167965ad.0.1789614186089; Wed, 16 Sep 2026 20:03:06 -0700 (PDT) Received: from b6ad5085b32f.. ([122.51.212.64]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2dd89f1b862sm19167845ad.71.2026.09.16.20.03.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 20:03:04 -0700 (PDT) From: Zihan Xi To: Simon Horman Cc: Julian Anastasov , Pablo Neira Ayuso , Florian Westphal , Phil Sutter , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, lvs-devel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, linux-kernel@vger.kernel.org, Zihan Xi Subject: [PATCH net v2 1/2] ipvs: avoid stack overflow from recursive connection expiration Date: Thu, 17 Sep 2026 03:02:51 +0000 Message-ID: <20260917030301.5502-1-zihanx@nebusec.ai> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When a controlled IPVS connection expires, its controller may be expired synchronously if it has no remaining controlled connections. A chain of controlled connections can then cause recursive calls to ip_vs_conn_expire() and exhaust the kernel stack during namespace cleanup. Make ip_vs_conn_del_put() report whether it deleted the controller timer. When it succeeds, continue expiration with the controller instead of calling ip_vs_conn_expire() recursively. This keeps chain cleanup synchronous while using one stack frame for the whole chain. Fixes: f9200a52eedf ("ipvs: avoid expiring many connections from timer") Cc: stable@vger.kernel.org Reported-by: Vega Assisted-by: LLM Co-developed-by: Luxing Yin Signed-off-by: Luxing Yin Signed-off-by: Zihan Xi Acked-by: Julian Anastasov --- changes in v2: - Use a repeat path for controller cleanup so expiration stays synchronous without recursive calls or extra timer ticks. - v1 Link: https://lore.kernel.org/all/cover.1789110326.git.zihanx@nebusec.ai/ net/netfilter/ipvs/ip_vs_conn.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_con= n.c index 6fa3e1dc534c3..c7b88ce1765dc 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -1331,17 +1331,18 @@ static void ip_vs_conn_del(struct ip_vs_conn *cp) } =20 /* Try to delete connection while holding reference */ -static void ip_vs_conn_del_put(struct ip_vs_conn *cp) +static bool ip_vs_conn_del_put(struct ip_vs_conn *cp) { if (timer_delete(&cp->timer)) { /* Drop cp->control chain too */ if (cp->control) cp->timeout =3D 0; __ip_vs_conn_put(cp); - ip_vs_conn_expire(&cp->timer); - } else { - __ip_vs_conn_put(cp); + return true; } + + __ip_vs_conn_put(cp); + return false; } =20 static void ip_vs_conn_expire(struct timer_list *t) @@ -1349,6 +1350,7 @@ static void ip_vs_conn_expire(struct timer_list *t) struct ip_vs_conn *cp =3D timer_container_of(cp, t, timer); struct netns_ipvs *ipvs =3D cp->ipvs; =20 +repeat: /* * do I control anybody? */ @@ -1358,6 +1360,7 @@ static void ip_vs_conn_expire(struct timer_list *t) /* Unlink conn if not referenced anymore */ if (likely(ip_vs_conn_unlink(cp))) { struct ip_vs_conn *ct =3D cp->control; + bool next =3D false; =20 /* delete the timer if it is activated by other users */ timer_delete(&cp->timer); @@ -1372,7 +1375,7 @@ static void ip_vs_conn_expire(struct timer_list *t) (!(ct->flags & IP_VS_CONN_F_TEMPLATE) || !(ct->state & IP_VS_CTPL_S_ASSURED))) { IP_VS_DBG(4, "drop controlling connection\n"); - ip_vs_conn_del_put(ct); + next =3D ip_vs_conn_del_put(ct); } else if (has_ref) { __ip_vs_conn_put(ct); } @@ -1402,6 +1405,10 @@ static void ip_vs_conn_expire(struct timer_list *t) else call_rcu(&cp->rcu_head, ip_vs_conn_rcu_free); atomic_dec(&ipvs->conn_count); + if (next) { + cp =3D ct; + goto repeat; + } return; } =20 --=20 2.43.0 From nobody Fri Sep 25 03:16:14 2026 Received: from mail-pj2-f13.google.com (mail-pj2-f13.google.com [74.125.227.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99628347FCD for ; Thu, 17 Sep 2026 03:03:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.141 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789614195; cv=none; b=BZWabQkSlfAn4PlzewbX2TUrTwvqBx5994x9VLiy2OH2C1FuklncIdPrB9ACPmPr6VD/zea22F8/kW1uhbEWOhJCwgOHP//W3uOi3ef1PH+zphJf/I8EgZ9rbji4cKWUlcLIpSx5p+ly/e720dUAi0ffSfeeZI6IQLJ6BM/xSQE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789614195; c=relaxed/simple; bh=ZAnMJFfRyn/L7UjKQ6wtOpZX1ERwvLKzcxMf+sbJyxU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=D+SKahGNB3l98zSoIbc0V23hT3RxEWTeM6WP0PAm1mFsWbPGgukFqfcg12teDP6uiFCPEgd9dtclgUhMtQ2+VHpbgLnF8K2X5h/DIRWVKx/yRjyAmnkFmXpEtjceBB9UhvV7t2gXelWKJxA73SbZZpQcQUVSNIVj1uWdt9IxGzY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai; spf=pass smtp.mailfrom=nebusec.ai; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b=ko2XybKf; arc=none smtp.client-ip=74.125.227.141 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nebusec.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nebusec.ai header.i=@nebusec.ai header.b="ko2XybKf" Received: by mail-pj2-f13.google.com with SMTP id d9443c01a7336-2d8fb334ddcso3248825ad.0 for ; Wed, 16 Sep 2026 20:03:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nebusec.ai; s=google; t=1789614190; x=1790218990; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=bEiJ73gdk+1H2UniqJzXdx9Ojg0hZPLKGrnSs4IPJHI=; b=ko2XybKf+ORIdYCZGisQEx+vJ90W4rwUFC+yt/UmDoIucUX3CJlNfEx/m0E5hYYiiF vE3yYs7g03ua78cYT/714tTFpd+T00ig3wnoE6+NSYH70jYFyeqF4rkzXytzfYUkJo8X /fG5dy0XxE4zFdIRt8GglWF89aeWyPpK14Q3aK/W3Veco3WmWhwDMNUeTWp+6QMiAcTS 641xbiHUYWoe5ffuGxAMXfFsrRfR9G0qgGvuQGLLcfAjVSVy5lolL8J5Sp7nz/TXNseI FjlOW51EO+2GWMPwo0rKZm/mMldNTQC8TaZ77cPHBtGFvzAgu9NpMuaTsvD9nDj0S5/P LmsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789614190; x=1790218990; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=bEiJ73gdk+1H2UniqJzXdx9Ojg0hZPLKGrnSs4IPJHI=; b=0gRxsoBGFIRDQG+z3sxCTYCgyArsCG9NKHAgCv0ndnl6LL/F460gXLiT0oHspCH/EV rMUw2YTvBwp9IS97Y60SWkUyMA4DLLxzFlN5yLnf+cOYco8Nr2VkVYiIS68EsbewfKZI CBolSzxY1CWzqkb/cEidymtumlDGQbMiDFyGuNmEepy/XREcnFw8E7QVYY3QSsl9foiI ki503ZNtDvJhKIyryfi3VD37NsGTkpRoud4mge9YM54Bexv1e99dbsd7SAXnzyPWXvBA lGgR69DMLL39XvGJuQYqhFYKkPAOqeJ66IdNAlIMWQeX0xKzTuhoh2ypk7LXJOxfFMZh v8uw== X-Forwarded-Encrypted: i=1; AKwUvBw4ThErEEjHY1HZLvzxIZhm7IMTPDrzHH80YzB6ULhKFiVcWqq61syxgW3V/iYdN1WvtlGc7gcc/OHVIlk=@vger.kernel.org X-Gm-Message-State: AFuF++mjgBLEj/jyDMmOW8LnnwhYJdIgbr84JsGKErH3ijaOVy8J8vdN nCVXW1LUMOqT3/ac4FzAC2AkA929Mjgk/jptcIGPsKSwY5rywLsrQLW7QrNLDHWCUZhy X-Gm-Gg: AYBFou329f64PjHIxMDWtfkFX10zlneAoRbObQKJE+/v6N7Fb5y8VALDv/kxckRzkil OEwT+c5OdHRbT417uUjf7MokksyR7EtZqhBWE24SBupRE/ZQSbAmJNMIa4TLmPUi+7oDWyjeg/m wzyA1a72/Ce8KchdrkURjJCHyPSS5ItcX8SODcUX/CRW2f9ghlOm/nCTMv01raCse+NxXrjFdTn rkL/0GibtAzlpWDH7at52wflmBBIRVCt4O+6J41DbiQF0JVtLNooaZVejRsKeauXGC5lFmMoqEk Y2dbbtT2tZWxsrl9Lf9hpMZYXjJNZy7kCtAWN37rUjSd1izQ4sm5xtb+GzmORQbAfUdx2egluq0 wYqMDmbqT9NfFOGdNjEW34aly3t0fA2NLgnxJd4gZ9yV++AWdvr0FrawBqCxYelEgx8lippM3+I eS2GeSPfRwBd0riJi9/5fI3HpTKUbjBkyUNlUcBjgZLWQqTh6hopiv+D/LLXKRmwzy4Qq8o6CbN TcIdQhStGLrdWGRfuxO/uzdo0/XJlilpdyD/Z5S X-Received: by 2002:a17:902:ebc3:b0:2d7:107c:917b with SMTP id d9443c01a7336-2dd8ccaa304mr114450195ad.0.1789614190034; Wed, 16 Sep 2026 20:03:10 -0700 (PDT) Received: from b6ad5085b32f.. ([122.51.212.64]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2dd89f1b862sm19167845ad.71.2026.09.16.20.03.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 20:03:09 -0700 (PDT) From: Zihan Xi To: Simon Horman Cc: Julian Anastasov , Pablo Neira Ayuso , Florian Westphal , Phil Sutter , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, lvs-devel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, linux-kernel@vger.kernel.org, Zihan Xi Subject: [PATCH net v2 2/2] ipvs: reject FTP control ports as data ports Date: Thu, 17 Sep 2026 03:02:52 +0000 Message-ID: <20260917030301.5502-2-zihanx@nebusec.ai> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ip_vs_ftp_out() creates a wildcard data connection from the server-advertised passive port. If that port is one of the configured FTP control ports, ip_vs_conn_new() binds the FTP helper to the new connection again. A subsequent wildcard lookup can then extend a controlled-connection chain. Reject zero and configured control ports before creating passive connections. For active mode, reject a zero client port and a data port derived from a configured control port. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Vega Assisted-by: LLM Co-developed-by: Luxing Yin Signed-off-by: Luxing Yin Signed-off-by: Zihan Xi --- changes in v2: - Reject the data port derived from a configured control port in ip_vs_ftp_in() to cover the active-mode bypass. - v1 Link: https://lore.kernel.org/all/cover.1789110326.git.zihanx@nebusec.ai/ net/netfilter/ipvs/ip_vs_ftp.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index 9e3e005a82635..4822a1a75212d 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -62,6 +62,17 @@ static unsigned short ports[IP_VS_APP_MAX_PORTS] =3D {21= , 0}; module_param_array(ports, ushort, &ports_count, 0444); MODULE_PARM_DESC(ports, "Ports to monitor for FTP control commands"); =20 +static bool is_control_port(u16 port) +{ + unsigned int i; + + for (i =3D 0; i < ports_count; i++) { + if (ports[i] =3D=3D port) + return true; + } + return false; +} + =20 static char *ip_vs_ftp_data_ptr(struct sk_buff *skb, struct ip_vs_iphdr *i= pvsh) { @@ -319,6 +330,10 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct= ip_vs_conn *cp, return 1; } =20 + /* Do not redirect data to control ports */ + if (!port || is_control_port(ntohs(port))) + return 0; + /* Now update or create a connection entry for it */ { struct ip_vs_conn_param p; @@ -529,6 +544,9 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct i= p_vs_conn *cp, return 1; } =20 + if (!port || is_control_port(ntohs(cp->vport) - 1)) + return 0; + /* Passive mode off */ cp->app_data =3D (void *) IP_VS_FTP_ACTIVE; =20 --=20 2.43.0