]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: synproxy: fix unaligned memory access in timestamp adjustment
authorFernando Fernandez Mancera <fmancera@suse.de>
Tue, 26 May 2026 21:58:29 +0000 (23:58 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 5 Jun 2026 11:11:55 +0000 (13:11 +0200)
Use get_unaligned_be32() and put_unaligned_be32() to safely read and
write the timestamp fields. This prevents performance degradation due to
unaligned memory access or even a crash on strict alignment
architectures.

This follows the implementation of timestamp parsing in the networking
stack at tcp_parse_options() and synproxy_parse_options().

Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_synproxy_core.c

index a0bcf188810d1392ee5c7d7e2041ddc076dc16a6..acd360515972f7889adb03b37f01a8ccb30df188 100644 (file)
@@ -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;
+       u32 new, old;
 
        if (synproxy->tsoff == 0)
                return true;
@@ -221,18 +221,17 @@ 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);
+                                       old = get_unaligned_be32(&op[2]);
+                                       new = old - synproxy->tsoff;
+                                       put_unaligned_be32(new, &op[2]);
                                } else {
-                                       ptr = (__be32 *)&op[6];
-                                       old = *ptr;
-                                       *ptr = htonl(ntohl(*ptr) +
-                                                    synproxy->tsoff);
+                                       old = get_unaligned_be32(&op[6]);
+                                       new = old + synproxy->tsoff;
+                                       put_unaligned_be32(new, &op[6]);
                                }
                                inet_proto_csum_replace4(&th->check, skb,
-                                                        old, *ptr, false);
+                                                        cpu_to_be32(old),
+                                                        cpu_to_be32(new), false);
                        }
                        optoff += op[1];
                }