svn commit: r206637 - in head: sbin/ifconfig share/man/man4 sys/net
Xin LI
delphij at FreeBSD.org
Wed Apr 14 22:02:20 UTC 2010
Author: delphij
Date: Wed Apr 14 22:02:19 2010
New Revision: 206637
URL: http://svn.freebsd.org/changeset/base/206637
Log:
When an underlying ioctl(2) handler returns an error, our ioctl(2)
interface considers that it hits a fatal error, and will not copyout
the request structure back for _IOW and _IOWR ioctls, keeping them
untouched.
The previous implementation of the SIOCGIFDESCR ioctl intends to
feed the buffer length back to userland. However, if we return
an error, the feedback would be defeated and ifconfig(8) would
trap into an infinite loop.
This commit changes SIOCGIFDESCR to set buffer field to NULL to
indicate the previous ENAMETOOLONG case.
Reported by: bschmidt
MFC after: 2 weeks
Modified:
head/sbin/ifconfig/ifconfig.c
head/share/man/man4/netintro.4
head/sys/net/if.c
Modified: head/sbin/ifconfig/ifconfig.c
==============================================================================
--- head/sbin/ifconfig/ifconfig.c Wed Apr 14 21:59:22 2010 (r206636)
+++ head/sbin/ifconfig/ifconfig.c Wed Apr 14 22:02:19 2010 (r206637)
@@ -922,19 +922,20 @@ status(const struct afswtch *afp, const
ifr.ifr_buffer.buffer = descr;
ifr.ifr_buffer.length = descrlen;
if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) {
- if (strlen(descr) > 0)
- printf("\tdescription: %s\n", descr);
- break;
- } else if (errno == ENAMETOOLONG)
- descrlen = ifr.ifr_buffer.length;
- else
- break;
- } else {
+ if (ifr.ifr_buffer.buffer == descr) {
+ if (strlen(descr) > 0)
+ printf("\tdescription: %s\n",
+ descr);
+ } else if (ifr.ifr_buffer.length > descrlen) {
+ descrlen = ifr.ifr_buffer.length;
+ continue;
+ }
+ }
+ } else
warn("unable to allocate memory for interface"
"description");
- break;
- }
- };
+ break;
+ }
if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
if (ifr.ifr_curcap != 0) {
Modified: head/share/man/man4/netintro.4
==============================================================================
--- head/share/man/man4/netintro.4 Wed Apr 14 21:59:22 2010 (r206636)
+++ head/share/man/man4/netintro.4 Wed Apr 14 22:02:19 2010 (r206637)
@@ -32,7 +32,7 @@
.\" @(#)netintro.4 8.2 (Berkeley) 11/30/93
.\" $FreeBSD$
.\"
-.Dd January 26, 2010
+.Dd April 14, 2010
.Dt NETINTRO 4
.Os
.Sh NAME
@@ -292,8 +292,11 @@ field of
struct passed in as parameter, and the length would include
the terminating nul character.
If there is not enough space to hold the interface length,
-no copy would be done and an
-error would be returned.
+no copy would be done and the
+.Va buffer
+field of
+.Va ifru_buffer
+would be set to NULL.
The kernel will store the buffer length in the
.Va length
field upon return, regardless whether the buffer itself is
Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c Wed Apr 14 21:59:22 2010 (r206636)
+++ head/sys/net/if.c Wed Apr 14 22:02:19 2010 (r206637)
@@ -2049,14 +2049,13 @@ ifhwioctl(u_long cmd, struct ifnet *ifp,
case SIOCGIFDESCR:
error = 0;
sx_slock(&ifdescr_sx);
- if (ifp->if_description == NULL) {
- ifr->ifr_buffer.length = 0;
+ if (ifp->if_description == NULL)
error = ENOMSG;
- } else {
+ else {
/* space for terminating nul */
descrlen = strlen(ifp->if_description) + 1;
if (ifr->ifr_buffer.length < descrlen)
- error = ENAMETOOLONG;
+ ifr->ifr_buffer.buffer = NULL;
else
error = copyout(ifp->if_description,
ifr->ifr_buffer.buffer, descrlen);
More information about the svn-src-head
mailing list