Jiri Slaby 9e4280
From: Geert Uytterhoeven <geert@linux-m68k.org>
Jiri Slaby 9e4280
Date: Fri, 20 Dec 2019 14:31:40 +0100
Jiri Slaby 9e4280
Subject: net: dst: Force 4-byte alignment of dst_metrics
Jiri Slaby 9e4280
Git-commit: 258a980d1ec23e2c786e9536a7dd260bea74bae6
Jiri Slaby 9e4280
Patch-mainline: 5.5-rc3
Jiri Slaby 9e4280
References: networking-stable-19_12_28
Jiri Slaby 9e4280
Jiri Slaby 9e4280
When storing a pointer to a dst_metrics structure in dst_entry._metrics,
Jiri Slaby 9e4280
two flags are added in the least significant bits of the pointer value.
Jiri Slaby 9e4280
Hence this assumes all pointers to dst_metrics structures have at least
Jiri Slaby 9e4280
4-byte alignment.
Jiri Slaby 9e4280
Jiri Slaby 9e4280
However, on m68k, the minimum alignment of 32-bit values is 2 bytes, not
Jiri Slaby 9e4280
4 bytes.  Hence in some kernel builds, dst_default_metrics may be only
Jiri Slaby 9e4280
2-byte aligned, leading to obscure boot warnings like:
Jiri Slaby 9e4280
Jiri Slaby 9e4280
    WARNING: CPU: 0 PID: 7 at lib/refcount.c:28 refcount_warn_saturate+0x44/0x9a
Jiri Slaby 9e4280
    refcount_t: underflow; use-after-free.
Jiri Slaby 9e4280
    Modules linked in:
Jiri Slaby 9e4280
    CPU: 0 PID: 7 Comm: ksoftirqd/0 Tainted: G        W         5.5.0-rc2-atari-01448-g114a1a1038af891d-dirty #261
Jiri Slaby 9e4280
    Stack from 10835e6c:
Jiri Slaby 9e4280
	    10835e6c 0038134f 00023fa6 00394b0f 0000001c 00000009 00321560 00023fea
Jiri Slaby 9e4280
	    00394b0f 0000001c 001a70f8 00000009 00000000 10835eb4 00000001 00000000
Jiri Slaby 9e4280
	    04208040 0000000a 00394b4a 10835ed4 00043aa8 001a70f8 00394b0f 0000001c
Jiri Slaby 9e4280
	    00000009 00394b4a 0026aba8 003215a4 00000003 00000000 0026d5a8 00000001
Jiri Slaby 9e4280
	    003215a4 003a4361 003238d6 000001f0 00000000 003215a4 10aa3b00 00025e84
Jiri Slaby 9e4280
	    003ddb00 10834000 002416a8 10aa3b00 00000000 00000080 000aa038 0004854a
Jiri Slaby 9e4280
    Call Trace: [<00023fa6>] __warn+0xb2/0xb4
Jiri Slaby 9e4280
     [<00023fea>] warn_slowpath_fmt+0x42/0x64
Jiri Slaby 9e4280
     [<001a70f8>] refcount_warn_saturate+0x44/0x9a
Jiri Slaby 9e4280
     [<00043aa8>] printk+0x0/0x18
Jiri Slaby 9e4280
     [<001a70f8>] refcount_warn_saturate+0x44/0x9a
Jiri Slaby 9e4280
     [<0026aba8>] refcount_sub_and_test.constprop.73+0x38/0x3e
Jiri Slaby 9e4280
     [<0026d5a8>] ipv4_dst_destroy+0x5e/0x7e
Jiri Slaby 9e4280
     [<00025e84>] __local_bh_enable_ip+0x0/0x8e
Jiri Slaby 9e4280
     [<002416a8>] dst_destroy+0x40/0xae
Jiri Slaby 9e4280
Jiri Slaby 9e4280
Fix this by forcing 4-byte alignment of all dst_metrics structures.
Jiri Slaby 9e4280
Jiri Slaby 9e4280
Fixes: e5fd387ad5b30ca3 ("ipv6: do not overwrite inetpeer metrics prematurely")
Jiri Slaby 9e4280
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Jiri Slaby 9e4280
Signed-off-by: David S. Miller <davem@davemloft.net>
Jiri Slaby 9e4280
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby 9e4280
---
Jiri Slaby 9e4280
 include/net/dst.h |    2 +-
Jiri Slaby 9e4280
 1 file changed, 1 insertion(+), 1 deletion(-)
Jiri Slaby 9e4280
Jiri Slaby 9e4280
--- a/include/net/dst.h
Jiri Slaby 9e4280
+++ b/include/net/dst.h
Jiri Slaby 9e4280
@@ -108,7 +108,7 @@ struct dst_entry {
Jiri Slaby 9e4280
 struct dst_metrics {
Jiri Slaby 9e4280
 	u32		metrics[RTAX_MAX];
Jiri Slaby 9e4280
 	atomic_t	refcnt;
Jiri Slaby 9e4280
-};
Jiri Slaby 9e4280
+} __aligned(4);		/* Low pointer bits contain DST_METRICS_FLAGS */
Jiri Slaby 9e4280
 extern const struct dst_metrics dst_default_metrics;
Jiri Slaby 9e4280
 
Jiri Slaby 9e4280
 u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);