Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 30 Jan 2002 22:46:21 +0100
From:      Volker Stolz <stolz@hyperion.informatik.rwth-aachen.de>
To:        alpha@freebsd.org
Subject:   rpc.statd/SIOCGIFCONF revisited
Message-ID:  <20020130224621.A14154@i2.informatik.rwth-aachen.de>

next in thread | raw e-mail | index | archive | help

--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Here's another try after the previous patch did mor good than harm.
What happens is this: the ioctl fills a buffer with various entries
for interfaces. If it's a sockaddr, everything goes well, that's
7x8 = 56 bytes. Unluckily, for inet6, you get 28 bytes.

In your buffer that means something like
--|--|--|...
56 28 XX
Now the userland code in e.g. libc/rpc/get_myaddress.c memcpy tried
now to access XX which obviusly isn't at an 8 byte aligned address.

memcpy() *should* be able to copy this region. *But*:
memcpy() gets optimized by gcc to use floating point registers
(unless you specify -fno-builtin). These instructions can only work
on double word aligned data :-/ Something similar happens when
you use an assignment like foo = *bar.

If you use -fno-builtin, get_myaddress will crash at
  *addr = *((struct sockaddr_in *)&ifrn->ifr_addr);
for a similar reason (the address has to be double word aligned
or the ldq will throw...

You can find several hints in itojun's and on NetBSD, boling down
to inet6 not being LP64 friendly, and SIOCGIFCONF being especially
nasty.

The attached patch *should* do the following: copy the requested
number of bytes but advance to the next aligned positioned and
update the sa_len entry only in the structure returned to userland.
Thus, if you just use the sa_len entry without resorting to 
sizeof() your application should work fine.

Comments are definetly appreciated. I cannot claim that I 
understand everything of the stuff going on there, so I'd
like to get some thumbs up/down from savvier people.
-- 
Wonderful \hbox (0.80312pt too nice) in paragraph at lines 16--18
Volker Stolz * stolz@i2.informatik.rwth-aachen.de
Please use PGP or S/MIME for correspondence!

--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="alpha.patch"

--- sys/net/if.c.orig	Wed Jan 30 21:25:50 2002
+++ sys/net/if.c	Wed Jan 30 21:34:27 2002
@@ -1318,17 +1318,20 @@
 						sizeof (ifr));
 				ifrp++;
 			} else {
-				if (space < sizeof (ifr) + sa->sa_len -
+				if (space < sizeof (ifr) + _ALIGN(sa->sa_len) -
 					    sizeof(*sa))
 					break;
-				space -= sa->sa_len - sizeof(*sa);
+				space -= _ALIGN(sa->sa_len) - sizeof(*sa);
 				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
 						sizeof (ifr.ifr_name));
 				if (error == 0)
 				    error = copyout((caddr_t)sa,
 				      (caddr_t)&ifrp->ifr_addr, sa->sa_len);
-				ifrp = (struct ifreq *)
-					(sa->sa_len + (caddr_t)&ifrp->ifr_addr);
+				/* Update sa_len to aligned value in output */
+				ifrp->ifr_addr.sa_len = _ALIGN(sa->sa_len);
+				/* Advance ptr, accounting for spilled padding, too */
+				ifrp = _ALIGN((struct ifreq *)
+					(sa->sa_len + (caddr_t)&ifrp->ifr_addr));
 			}
 			if (error)
 				break;

--RnlQjJ0d97Da+TV1--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-alpha" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020130224621.A14154>