networking: alignment exception in ioctl(SIOCGIFCONF)

Access memory using a byte stream when copying to avoid unaligned
access. update #1401
This commit is contained in:
Till Straumann
2015-02-23 10:46:22 -05:00
committed by Gedare Bloom
parent 0863e8e390
commit 70148eef28

View File

@@ -719,9 +719,10 @@ ifconf(u_long cmd, caddr_t data)
struct ifnet *ifp = ifnet; struct ifnet *ifp = ifnet;
struct ifaddr *ifa; struct ifaddr *ifa;
struct ifreq ifr, *ifrp; struct ifreq ifr, *ifrp;
char *ifrpc;
int space = ifc->ifc_len, error = 0; int space = ifc->ifc_len, error = 0;
ifrp = ifc->ifc_req; ifrpc = (char*)ifc->ifc_req;
for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) { for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
char workbuf[64]; char workbuf[64];
int ifnlen; int ifnlen;
@@ -735,11 +736,11 @@ ifconf(u_long cmd, caddr_t data)
if ((ifa = ifp->if_addrlist) == 0) { if ((ifa = ifp->if_addrlist) == 0) {
bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
error = copyout((caddr_t)&ifr, (caddr_t)ifrp, error = copyout((caddr_t)&ifr, (caddr_t)ifrpc,
sizeof (ifr)); sizeof (ifr));
if (error) if (error)
break; break;
space -= sizeof (ifr), ifrp++; space -= sizeof (ifr); ifrpc+=sizeof(ifr);
} else } else
for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) { for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {
struct sockaddr *sa = ifa->ifa_addr; struct sockaddr *sa = ifa->ifa_addr;
@@ -749,27 +750,27 @@ ifconf(u_long cmd, caddr_t data)
(struct osockaddr *)&ifr.ifr_addr; (struct osockaddr *)&ifr.ifr_addr;
ifr.ifr_addr = *sa; ifr.ifr_addr = *sa;
osa->sa_family = sa->sa_family; osa->sa_family = sa->sa_family;
error = copyout((caddr_t)&ifr, (caddr_t)ifrp, error = copyout((caddr_t)&ifr, (caddr_t)ifrpc,
sizeof (ifr)); sizeof (ifr));
ifrp++; ifrpc+=sizeof(ifr);
} else } else
#endif #endif
if (sa->sa_len <= sizeof(*sa)) { if (sa->sa_len <= sizeof(*sa)) {
ifr.ifr_addr = *sa; ifr.ifr_addr = *sa;
error = copyout((caddr_t)&ifr, (caddr_t)ifrp, error = copyout((caddr_t)&ifr, (caddr_t)ifrpc,
sizeof (ifr)); sizeof (ifr));
ifrp++; ifrpc+=sizeof(ifr);
} else { } else {
space -= sa->sa_len - sizeof(*sa); space -= sa->sa_len - sizeof(*sa);
if (space < sizeof (ifr)) if (space < sizeof (ifr))
break; break;
error = copyout((caddr_t)&ifr, (caddr_t)ifrp, error = copyout((caddr_t)&ifr, (caddr_t)ifrpc,
sizeof (ifr.ifr_name)); sizeof (ifr.ifr_name));
ifrpc+=sizeof(ifr.ifr_name);
if (error == 0) if (error == 0)
error = copyout((caddr_t)sa, error = copyout((caddr_t)sa,
(caddr_t)&ifrp->ifr_addr, sa->sa_len); (caddr_t)ifrpc, sa->sa_len);
ifrp = (struct ifreq *) ifrpc += sa->sa_len;
(sa->sa_len + (caddr_t)&ifrp->ifr_addr);
} }
if (error) if (error)
break; break;