Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Jul 1999 14:57:52 +0200 (SAT)
From:      Reinier Bezuidenhout <rbezuide@oskar.nanoteq.co.za>
To:        freebsd-hackers@freebsd.org
Cc:        phk@freebsd.org
Subject:   if.c and ifconf() possible error ?
Message-ID:  <199907291257.OAA05610@oskar.nanoteq.co.za>

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


When a program calls the SIOCGIFCONF ioctl and the
function ifconf in sys/net/if.c is executed, the value
that is returned in ifc.ifc_len, is that the value of
the amount of data filled in ... or can it be larger ??

Example ...

The calling process sends 1000 as the size of the buffer.

ifconf loops through the number of interfaces and sees that
there are more interfaces than can fit into this buffer.  It
then fills the buffer to 960 bytes fulle and the one of
the checks fail ... should ifconf return the value
960 in ifc.ifc_len or should it return 1000 ??

The reason I ask .. it seems like it returns 1000 rather than 
960 ... this causes sendmail to think that there is still
another device in the list ... it tries to read this ... and it 
gets a structure with a lot of zero's (because ifconf rightly so
didn't fill it in) but the next one causes a segmentation fault
in sendmails conf.c in the function load_if_names.

This ONLY happens with sendmail and if you have more than 230 odd
onterfaces configured in your kernel AND NO interfaces are
ifconfiged e.g. all are deleted.

If you increase the value given by sendmail to the SIOCGIFCONF call
(a bigger buffer) everything works fine.

If it is the job of the ifconf function to return the correct value
in ifc.ifc_len, I've included a patch below which causes the ifconf 
function to return only how much it filled into the buffer and nothing
more.  It fixes the problem with sendmail (actually newaliases).

Please check the changes as I haven't tested every possible senario.

Thanx
Reinier



*** if.c.orig	Thu Jul 29 14:30:11 1999
--- if.c	Thu Jul 29 14:34:45 1999
***************
*** 814,820 ****
  	register struct ifnet *ifp = ifnet.tqh_first;
  	register struct ifaddr *ifa;
  	struct ifreq ifr, *ifrp;
! 	int space = ifc->ifc_len, error = 0;
  
  	ifrp = ifc->ifc_req;
  	for (; space > sizeof (ifr) && ifp; ifp = ifp->if_link.tqe_next) {
--- 814,820 ----
  	register struct ifnet *ifp = ifnet.tqh_first;
  	register struct ifaddr *ifa;
  	struct ifreq ifr, *ifrp;
! 	int space = ifc->ifc_len, error = 0, unused = 0;
  
  	ifrp = ifc->ifc_req;
  	for (; space > sizeof (ifr) && ifp; ifp = ifp->if_link.tqe_next) {
***************
*** 857,862 ****
--- 857,864 ----
  						sizeof (ifr));
  				ifrp++;
  			} else {
+ 				/* keep the value of unused space so far */
+ 				unused = space;
  				space -= sa->sa_len - sizeof(*sa);
  				if (space < sizeof (ifr))
  					break;
***************
*** 871,879 ****
  			if (error)
  				break;
  			space -= sizeof (ifr);
  		}
  	}
! 	ifc->ifc_len -= space;
  	return (error);
  }
  
--- 873,883 ----
  			if (error)
  				break;
  			space -= sizeof (ifr);
+ 			/* reset the unused space to zero */
+ 			unused = 0;
  		}
  	}
! 	ifc->ifc_len -= space + unused;
  	return (error);
  }
  


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




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