]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tcp: initialize standalone TCP-AO response padding
authorYizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Mon, 13 Jul 2026 10:56:30 +0000 (18:56 +0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 21 Jul 2026 22:24:36 +0000 (15:24 -0700)
tcp_v4_send_ack() and tcp_v6_send_response() construct standalone TCP
responses with TCP-AO options.  The option length carries the actual MAC
length, but the TCP header length includes the option rounded up to a
four-byte boundary.

tcp_ao_hash_hdr() writes the MAC only.  Thus, when the MAC length is not
four-byte aligned, the one to three bytes after the MAC are left
uninitialized and may be transmitted.  For the normal TCP-AO hashing
mode, those bytes also have to be initialized before computing the MAC.

Initialize only the alignment padding in the TCP-AO branches, before
hashing the header.  Use TCPOPT_NOP, as in the normal TCP-AO output path.
This avoids adding work to non-AO TCP responses while preserving a valid
authenticated header.

Fixes: decde2586b34 ("net/tcp: Add TCP-AO sign to twsk")
Fixes: da7dfaa6d6f7 ("net/tcp: Consistently align TCP-AO option in the header")
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>
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260713105631.8616-1-zhaoyz24@mails.tsinghua.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv4/tcp_ipv4.c
net/ipv6/tcp_ipv6.c

index 4a46da375043be26bcbb282a0b0c3ba85bfc5186..aada52769057731c15aa760b5a3232a01c1b5cbc 100644 (file)
@@ -971,6 +971,9 @@ static void tcp_v4_send_ack(const struct sock *sk,
                                          key->rcv_next);
                arg.iov[0].iov_len += tcp_ao_len_aligned(key->ao_key);
                rep.th.doff = arg.iov[0].iov_len / 4;
+               memset((u8 *)&rep.opt[offset] + tcp_ao_maclen(key->ao_key),
+                      TCPOPT_NOP, tcp_ao_len_aligned(key->ao_key) -
+                                   tcp_ao_len(key->ao_key));
 
                tcp_ao_hash_hdr(AF_INET, (char *)&rep.opt[offset],
                                key->ao_key, key->traffic_key,
index 522ba45ce9b759a6a76fd8603400097bc99c60c6..9e9155b1b3aa752631d8a2e4db73fb39a229b9ae 100644 (file)
@@ -923,6 +923,8 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
                                (tcp_ao_len(key->ao_key) << 16) |
                                (key->ao_key->sndid << 8) |
                                (key->rcv_next));
+               memset((u8 *)topt + tcp_ao_maclen(key->ao_key), TCPOPT_NOP,
+                      tcp_ao_len_aligned(key->ao_key) - tcp_ao_len(key->ao_key));
 
                tcp_ao_hash_hdr(AF_INET6, (char *)topt, key->ao_key,
                                key->traffic_key,