Hi,

On Sat, Jun 10, 2017 at 07:58:13PM +0200, Jeremie Courreges-Anglas wrote:
> OpenBSD:
> 
> struct ip {
> #if _BYTE_ORDER == _LITTLE_ENDIAN
>       u_int     ip_hl:4,              /* header length */
>                 ip_v:4;               /* version */
> #endif
> #if _BYTE_ORDER == _BIG_ENDIAN
>       u_int     ip_v:4,               /* version */
>                 ip_hl:4;              /* header length */
> #endif
> ...
> 
> u_char -> u_int.  Dunno if it matters to the compiler, I can take a look
> later.

I'm fairly sure it does matter.  An int is likely to be at least 16 bit, 
maybe 32 bit, so the compiler can assume "word aligned" - and *boom*.

(Wonder why it doesn't crash for Mator, as our buffer alignment in memory
should be fairly consistent - it might depend on crypto and compression
options, though)


> > old:
> >     if (iph->ip_v == 6)
> >
> > new:
> >     if (OPENVPN_IPH_GET_VER(*buf) == 6)
> >
> > this is an existing macro which takes an int argument, shifting and
> > masking the right bits, and since *buf is "uint8_t *buf", this should
> > both be correct and alignment-ignorant.  
> 
> See my proposed patch, also in this thread.  

"Copying around 20 bytes to ensure a single-byte access is really a
single-byte access" is definitely *not* the right way here.  So NAK on
that patch.

It will stop the crashes, of course, but since no other parts of 
struct ip are ever needed, it's just waste of CPU cycles.


> I merely copy/pasted the NetBSD code.

Uh?  Is this from the NetBSD ports tree?  Because our tun.c does not
have a single memcpy() today... :-)

Actually, my tun.c's TARGET_NETBSD version of write_tun() has something
similar to what I suggested:

        struct openvpn_iphdr *iph;

        iph = (struct openvpn_iphdr *) buf;

        if (OPENVPN_IPH_GET_VER(iph->version_len) == 6)

... slightly more speaking, and since "openvpn_iphdr" is a locally 
defined structure with "uchar version_len" at the very beginning, this
amounts to the same thing.


> > It might be less efficient than accessing the bit field - but then, it's 
> > the same work to do, so hopefully the compiler is smart enough to compile 
> > it to the same instructions.
> 
> master (32 bits access):
> 0x0000000000081844 <write_tun_header+100>:      ld  [ %i1 ], %g1
> 0x0000000000081848 <write_tun_header+104>:      sethi  %hi(0xf0000000), %g2
> 0x000000000008184c <write_tun_header+108>:      sethi  %hi(0x60000000), %g3
> 0x0000000000081850 <write_tun_header+112>:      and  %g1, %g2, %g1
> 0x0000000000081854 <write_tun_header+116>:      cmp  %g1, %g3
> 
> patched:
> 0x0000000000081844 <write_tun_header+100>:      ldub  [ %i1 ], %g1
> 0x0000000000081848 <write_tun_header+104>:      srl  %g1, 4, %g1
> 0x000000000008184c <write_tun_header+108>:      cmp  %g1, 6

Sounds like an improvement, at least in code size :-)  (but I have no 
idea how the performance of these operations compares)

... and I can see that the "master" version is going to fail on
unaligned packets...  so, needs fixing.

gert
-- 
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             g...@greenie.muc.de
fax: +49-89-35655025                        g...@net.informatik.tu-muenchen.de

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