Bug 202600

Summary: [patch] ndp(8): fix unaligned accesses
Product: Base System Reporter: Christian Weisgerber <naddy>
Component: binAssignee: Hiroki Sato <hrs>
Status: Open ---    
Severity: Affects Some People CC: hrs
Priority: --- Keywords: patch
Version: CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
ndp.c diff none

Description Christian Weisgerber freebsd_committer 2015-08-23 18:51:16 UTC
Created attachment 160262 [details]
ndp.c diff

ndp -p performs unaligned accesses on architectures that require strict alignment for 64-bit types (e.g. sparc64). Even if we trap these on FreeBSD rather than sending SIGBUS, this should be fixed.

The sysctl used to pass the prefix list uses a packed format:
  one struct in6_prefix, several struct sockaddr_in6,
  one struct in6_prefix, several struct sockaddr_in6,
  ...
This was fine when both structs had the same alignment requirement (int32_t).  However, there is a time_t in in6_prefix which has pushed that struct's alignment to int64_t.

The attached patch is taken from NetBSD (Martin Husemann):
http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.sbin/ndp/ndp.c.diff?r1=1.41&r2=1.42
"Simplify code to print the router/prefix list: use memcpy and local structs properly aligned on the stack to decode the binary format passed by the kernel - instead of (bogusly) assuming the format will obey all local alignement requirements."

The kernel side of this was fixed independently in r235681.
Comment 1 Christian Weisgerber freebsd_committer 2015-08-23 19:56:38 UTC
While there, I suggest to remove #ifdef ICMPV6CTL_ND6_DRLIST and the whole #else branch from rtrlist(), and #ifdef ICMPV6CTL_ND6_PRLIST and the #else branch from plist(). Those sysctls have been available for 14 years and the #else code has suffered bit rot and doesn't compile any longer.
Comment 2 Eitan Adler freebsd_committer freebsd_triage 2018-05-23 10:28:10 UTC
batch change of PRs untouched in 2018 marked "in progress" back to open.