From 344856b8adff03b48b2e2e83417e175189ba75b5 Mon Sep 17 00:00:00 2001 From: Jeffrey Hill Date: Mon, 23 Feb 2015 12:06:21 -0500 Subject: rpc: misaligned address exception in get_myaddress.c updates #2249 see #1401 --- cpukit/librpc/src/rpc/get_myaddress.c | 53 +++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/cpukit/librpc/src/rpc/get_myaddress.c b/cpukit/librpc/src/rpc/get_myaddress.c index 60357cff8f..1c7088ff92 100644 --- a/cpukit/librpc/src/rpc/get_myaddress.c +++ b/cpukit/librpc/src/rpc/get_myaddress.c @@ -45,13 +45,27 @@ static char *rcsid = "$FreeBSD: src/lib/libc/rpc/get_myaddress.c,v 1.17 2000/01/ #include #include #include +#include #include -#include #include #include #include #include + +/* + * Determine the size of an ifreq structure when addresses larger + * than the pifreq structure size may be returned from the kernel. + */ +static size_t ifreqSize ( struct ifreq *pifreq ) +{ + size_t size = pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name); + if ( size < sizeof ( *pifreq ) ) { + size = sizeof ( *pifreq ); + } + return size; +} + /* * don't use gethostbyname, which would invoke yellow pages * @@ -63,28 +77,32 @@ get_myaddress( struct sockaddr_in *addr) { int s; - char buf[BUFSIZ]; struct ifconf ifc; - struct ifreq ifreq, *ifr, *end; + struct ifreq ifreq, *ifr; int loopback = 0, gotit = 0; if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return(-1); } - ifc.ifc_len = sizeof (buf); - ifc.ifc_buf = buf; +again: + ifc.ifc_len = sizeof ( struct ifreq ) * 8u; + ifc.ifc_buf = malloc ( ifc.ifc_len ); + if ( ! ifc.ifc_buf ) { + _RPC_close(s); + return -1; + } if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { _RPC_close(s); + free ( ifc.ifc_buf ); return(-1); } -again: ifr = ifc.ifc_req; - end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - while (ifr < end) { - ifreq = *ifr; - if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + while ( ifc.ifc_len >= ifreqSize ( ifr ) ) { + ifreq = *ifr; + if (ioctl(s, SIOCGIFFLAGS, (char *) &ifreq ) < 0) { _RPC_close(s); + free ( ifc.ifc_buf ); return(-1); } if (((ifreq.ifr_flags & IFF_UP) && @@ -98,16 +116,21 @@ again: gotit = 1; break; } - if (ifr->ifr_addr.sa_len) - ifr = (struct ifreq *) ((caddr_t) ifr + - ifr->ifr_addr.sa_len - - sizeof(struct sockaddr)); - ifr++; + + const size_t len = ifreqSize ( ifr ); + ifc.ifc_len -= len; + /* + * RTEMS seems to require copy up to properly aligned + * boundary at the beginning of the buffer? + */ + memmove ( ifr, len + (char *) ifr, ifc.ifc_len ); } if (gotit == 0 && loopback == 0) { + free ( ifc.ifc_buf ); loopback = 1; goto again; } (void)_RPC_close(s); + free ( ifc.ifc_buf ); return (gotit ? 0 : -1); } -- cgit v1.2.3