synproxy_tstamp_adjust() reads and writes the TSval and TSecr fields of the TCP Timestamp option via direct __be32 pointer dereferences. These fields are at byte offsets 2 and 6 within the option, which are only 2-byte aligned — not 4-byte aligned for __be32 access. Replace with get_unaligned_be32() / put_unaligned_be32() to safely handle the unaligned access on strict-alignment architectures. Assisted-by: opencode:big-pickle Signed-off-by: Rosen Penev --- net/netfilter/nf_synproxy_core.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index ed00114f65f3..0a038b9b5169 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c @@ -191,7 +191,7 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff, const struct nf_conn_synproxy *synproxy) { unsigned int optoff, optend; - __be32 *ptr, old; + __be32 old; if (synproxy->tsoff == 0) return 1; @@ -221,18 +221,22 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff, if (op[0] == TCPOPT_TIMESTAMP && op[1] == TCPOLEN_TIMESTAMP) { if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { - ptr = (__be32 *)&op[2]; - old = *ptr; - *ptr = htonl(ntohl(*ptr) - - synproxy->tsoff); + u32 tsval = get_unaligned_be32(&op[2]); + u32 new_tsval = tsval - synproxy->tsoff; + + old = cpu_to_be32(tsval); + put_unaligned_be32(new_tsval, &op[2]); + inet_proto_csum_replace4(&th->check, skb, + old, cpu_to_be32(new_tsval), false); } else { - ptr = (__be32 *)&op[6]; - old = *ptr; - *ptr = htonl(ntohl(*ptr) + - synproxy->tsoff); + u32 tsecr = get_unaligned_be32(&op[6]); + u32 new_tsecr = tsecr + synproxy->tsoff; + + old = cpu_to_be32(tsecr); + put_unaligned_be32(new_tsecr, &op[6]); + inet_proto_csum_replace4(&th->check, skb, + old, cpu_to_be32(new_tsecr), false); } - inet_proto_csum_replace4(&th->check, skb, - old, *ptr, false); return 1; } optoff += op[1]; -- 2.54.0