>Synopsis: vxlan(4) unaligned traps crashes on alpha
>Category: alpha
>Environment:
System : OpenBSD 6.0
Details : OpenBSD 6.0 (GENERIC) #469: Wed Jul 27 03:13:14 MDT
2016
[email protected]:/usr/src/sys/arch/alpha/compile/G
ENERIC
Architecture: OpenBSD.alpha
Machine : alpha
>Description:
Creating a vxlan(4) instance and setting an IPv6 address on it will
cause an unaligned access fault on alpha, tested on my DS10 and
DS15 systems. In OpenBSD 5.9, the crash happened only after e.g. a
ping6(8) like ff02::1%vxlan0...
fatal kernel trap:
trap entry = 0x4 (unaligned access fault)
a0 = 0xfffffc0037333e7e
a1 = 0x28
a2 = 0x2
pc = 0xfffffc00007efb70
ra = 0xfffffc00007efb14
curproc = 0xfffffc003fc70268
pid = 8962, comm = ifconfig
panic: trap
Stopped at Debugger+0x8: lda sp,10(sp)
TID PID UID PRFLAGS PFLAGS CPU COMMAND
* 8962 8962 0 0x3 0 0 ifconfig
Debugger(4, fffffc0000ced0d0, fffffd01fc0003fd, 8, 3, fffffc0000000008) at
Debugger+0x8
panic(?, 28, 2, 4, fffffe0014cdf670, 8) at panic+0xcc
trap(?, ?, ?, ?, ?, 8) at trap+0x138
XentUna(?, ?, ?, ?, ?, 8) at XentUna+0x20
vxlan_output(?, 24, 2, fffffe0014cdfaa8, fffffe0014cdf8c8, 18) at
vxlan_output+0xa0
vxlanstart(?, ?, 2, fffffe0014cdfaa8, fffffe0014cdf8c8, 18) at
vxlanstart+0x64
ifq_dequeue(?, ?, 2, fffffe0014cdfaa8, fffffe0014cdf8c8, 18) at
ifq_dequeue+0x34
http://www.openbsd.org/ddb.html describes the minimum info required in bug
reports. Insufficient info makes it difficult to find and fix bugs.
ddb>
Once this was fixed, the machine crashes at an incoming packet on
the vxlan(4) interface.
fatal kernel trap:
trap entry = 0x4 (unaligned access fault)
a0 = 0xfffffc0001c63072
a1 = 0x28
a2 = 0x6
pc = 0xfffffc00007b6ab8
ra = 0xfffffc00007b68fc
curproc = 0xfffffc003fd5a960
pid = 82287, comm = softnet
panic: trap
Stopped at Debugger+0x8: lda sp,10(sp)
TID PID UID PRFLAGS PFLAGS CPU COMMAND
*82287 82287 0 0x14000 0x210 0 softnet
Debugger(1, fffffd01fc0003f8, fffffd01fc0003fd, 8, 3, fffffd0100000008) at
Debugger+0x8
panic(?, 28, 6, 4, fffffe0014d83c20, fffffc0000000008) at panic+0xcc
trap(?, ?, ?, ?, ?, fffffc0000000008) at trap+0x138
XentUna(?, ?, ?, ?, ?, fffffc0000000008) at XentUna+0x20
ip6_input(fffffc003ff85f00, d3f2152afb6f8db3, fffffc0000906360, 0, 0,
fffffc0037296e00) at ip6_input+0x208
ip6intr(fffffc003ff85f00, d3f2152afb6f8db3, fffffc0000906360, 0, 0,
fffffc0037296e00) at ip6intr+0x24
http://www.openbsd.org/ddb.html describes the minimum info required in bug
reports. Insufficient info makes it difficult to find and fix bugs.
ddb>
>How-To-Repeat:
For the first kernel trap:
# ifconfig vxlan0 create
# ifconfig vxlan0 inet6 2001:db8::1/32
Then, ping that address from the remote to cause another kernel
trap:
# ping6 2001:db8::1
>Fix:
I haven't fully understood how mbuf's work but by adding a m_pullup(9) after
M_PREPEND() seems to atleast make the first panic go away.
How many bytes for m_pullup? In vxlan_output, sizeof (*vi) work but should
we do more?
In vxlan_lookup, m_pullup by sizeof (*eh) was the only thing i could think
of trying.
I remember that back in 2002 (kernel/3037 by mickey@) we had similar
unaligned access issues with rl(4). How times go by...
TIA,
Dennis.
--- sys/net/if_vxlan.c.orig Thu Oct 6 10:15:03 2016
+++ sys/net/if_vxlan.c Thu Oct 13 17:24:17 2016
@@ -551,6 +551,11 @@
m_adj(m, skip);
ifp = &sc->sc_ac.ac_if;
+ m = m_pullup(m, sizeof(*eh));
+ if (m == NULL) {
+ ifp->if_ierrors++;
+ return (ENOBUFS);
+ }
if ((eh = mtod(m, struct ether_header *)) == NULL)
return (EINVAL);
@@ -594,6 +599,12 @@
/* VXLAN header */
M_PREPEND(m, sizeof(*vi), M_DONTWAIT);
+ if (m == NULL) {
+ ifp->if_oerrors++;
+ return (ENOBUFS);
+ }
+
+ m = m_pullup(m, sizeof(*vi));
if (m == NULL) {
ifp->if_oerrors++;
return (ENOBUFS);