Gert Doering <g...@greenie.muc.de> writes:

> Hi,
>
> On Fri, May 26, 2017 at 04:30:53PM +0200, Jeremie Courreges-Anglas wrote:
>> I am the maintainer of openvpn in the OpenBSD ports tree.  Here's
>> a report from Stefan Sperling (Cc'ed).
>> 
>> > An openvpn server running on OpenBSD/sparc64 6.1 crashes when a client
>> > connects and starts doing traffic. Is anyone else seeing this?
>
> Thanks for the report.  I'll look into it.
>
> Copying around the IP header doesn't feel like the proper solution, 
> though - it's basically replacing an unaligned access somewhere with
> a larger (unaligned!) mem copy, where most likely changing a word
> access to 2x byte access (etc) might achieve the same thing without
> copying.

Agreed, there's probably a better way to handle this.  The best
workaround I can think of would be using openvpn_iphdr /
OPENVPN_IPH_GET_VER, like the NetBSD code does.  It accesses only the
first byte of the buffer and thus shouldn't be affected by alignement
constraints.

This patch has been successfully tested (v4 and v6 traffic) by Stefan
Sperling on OpenBSD/sparc64, on top of the openvpn-2.4.2 release.

From 3f5cf7fa574c3bb7495bfb43d09e96c368702445 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Courr=C3=A8ges-Anglas?= <j...@wxcvbn.org>
Date: Sat, 10 Jun 2017 16:48:44 +0200
Subject: [PATCH] Fix an unaligned access on OpenBSD/sparc64

The pointer to the packet content doesn't seem to be word-aligned,
resulting in a SIGBUS when accessing it as a pointer to struct ip that
contains bit fields.

Replace with struct openvpn_iphdr and OPENVPN_IPH_GET_VER, which only
does a one byte access and thus isn't affected by alignement.
---
 src/openvpn/tun.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 3504fbf4..0ca0c19e 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -1654,11 +1654,11 @@ write_tun_header(struct tuntap *tt, uint8_t *buf, int len)
     {
         u_int32_t type;
         struct iovec iv[2];
-        struct ip *iph;
+        struct openvpn_iphdr *iph;
 
-        iph = (struct ip *) buf;
+        iph = (struct openvpn_iphdr *) buf;
 
-        if (iph->ip_v == 6)
+        if (OPENVPN_IPH_GET_VER(iph->version_len) == 6)
         {
             type = htonl(AF_INET6);
         }
-- 
2.13.0

>> To work around this, the patch below (also written by Stefan) was
>> committed in our ports tree.  TARGET_FREEBSD and TARGET_DRAGONFLY seem
>> to be affected too.
>
> FreeBSD/Sparc64 traps unaligned memory accesses and handles them 
> kernel-side.  So you'll see a slowdown, but no signal.

Sounds bad.  The proposed patch affects only OpenBSD and Mac OSX
(untested there, but looks safe); but FreeBSD and DragonflyBSD would
probably benefit from the same change.

> Linux/Sparc64 has the same restrictions (unaligned access causing a
> signal), but nobody has reported that yet, so maybe the underlying
> memory alignment of the allocated buffer happens to be good enough 
> there.

I don't know much about the memory allocator used in openvpn, but I'd
expect it to provide at least word-aligned pointers.

The code we're discussing is specific to BSD systems, another possible
reason why Linux looks unaffected.

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Attachment: signature.asc
Description: PGP signature

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to