]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ipvs: reset full ip_vs_seq structs in ip_vs_conn_new
authorYizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Thu, 2 Jul 2026 11:28:36 +0000 (19:28 +0800)
committerFlorian Westphal <fw@strlen.de>
Fri, 3 Jul 2026 12:45:21 +0000 (14:45 +0200)
Commit 9a05475cebdd ("ipvs: avoid kmem_cache_zalloc in
ip_vs_conn_new") changed ip_vs_conn_new() to allocate an ip_vs_conn
object with kmem_cache_alloc().  The function then initializes many
fields explicitly, but only resets in_seq.delta and out_seq.delta in the
two struct ip_vs_seq members.

That leaves init_seq and previous_delta uninitialized.  This is normally
harmless while the corresponding IP_VS_CONN_F_IN_SEQ or
IP_VS_CONN_F_OUT_SEQ flag is clear.  For connections learned from a sync
message, however, ip_vs_proc_conn() preserves those flags from
IP_VS_CONN_F_BACKUP_MASK and passes opt=NULL when the message omits
IPVS_OPT_SEQ_DATA.  In that case the new connection can be hashed with
SEQ flags set but with the rest of in_seq/out_seq still containing stale
slab data.

When a packet for such a connection is later handled by an IPVS
application helper, vs_fix_seq() and vs_fix_ack_seq() use
previous_delta and init_seq to rewrite TCP sequence numbers.  A malformed
sync message can therefore make forwarded packets carry stale slab bytes
in their TCP seq/ack numbers, and can also corrupt the forwarded TCP
flow.

Reset both struct ip_vs_seq members completely before publishing the
connection.  This matches the existing "reset struct ip_vs_seq" comment
and keeps the sequence-adjustment gates inactive unless valid sequence
data is installed later.

Fixes: 9a05475cebdd ("ipvs: avoid kmem_cache_zalloc in ip_vs_conn_new")
Cc: stable@vger.kernel.org
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Ao Wang <wangao@seu.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Assisted-by: Claude-Code:GLM-5.2
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/ipvs/ip_vs_conn.c

index cb36641f8d1cc103fab31e48c12a35367642d88b..6ed2622363f0d696c53c8317bba6b2ef0fb4c768 100644 (file)
@@ -1420,8 +1420,8 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af,
        cp->app = NULL;
        cp->app_data = NULL;
        /* reset struct ip_vs_seq */
-       cp->in_seq.delta = 0;
-       cp->out_seq.delta = 0;
+       memset(&cp->in_seq, 0, sizeof(cp->in_seq));
+       memset(&cp->out_seq, 0, sizeof(cp->out_seq));
 
        if (unlikely(flags & IP_VS_CONN_F_NO_CPORT)) {
                int af_id = ip_vs_af_index(cp->af);