[ECOS] IPv6 & DHCP stack corruption

Andrew Lunn andrew.lunn@ascom.ch
Wed Apr 2 08:47:00 GMT 2003


Hi Ken, Gary, et al

I found a problem with the dhcp client when IPv6 is enabled. In
do_dhcp_down_net, if IPv6 is enabled two extra ioctl calls are
made. This is being passed a struct ifreq. The comments in if.h
suggests this should actually take struct if_laddrreq, which is
bigger. During the ioctl, some addresses are copied into the
structure, which is too small and so the stack is corrupted. This
causes a crash on the synth target and will also affect any targets
where the stack grows down in memory.

Ken, could you explain what you are trying to achieve here? Why is
IPv4 code deleting the IPv6 link local address? When is it restored?

How should flags, prefixlen and addr be set when making the ioctl? At
the moment they are left uninitialized which i presume is wrong.

/*
 * Structure for SIOC[AGD]LIFADDR
 */
struct if_laddrreq {
	char	iflr_name[IFNAMSIZ];
	u_int	flags;
#define	IFLR_PREFIX	0x8000  /* in: prefix given  out: kernel fills id */
	u_int	prefixlen;         /* in/out */
	struct	sockaddr_storage addr;   /* in/out */
	struct	sockaddr_storage dstaddr; /* out */
};

        Thanks

                Andrew

Index: net/common//current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/common/current/ChangeLog,v
retrieving revision 1.27
diff -u -r1.27 ChangeLog
--- net/common//current/ChangeLog       21 Mar 2003 18:14:35 -0000      1.27
+++ net/common//current/ChangeLog       2 Apr 2003 08:34:13 -0000
@@ -1,3 +1,8 @@
+2003-04-02  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * src/dhcp_prot.c (do_dhcp_down_net): SIOCGLIFADDR and SIOCDLIFADDR
+       take if_laddrreq not ifreq. This caused stack corruption.
+
 2003-03-21  Nick Garnett  <nickg@balti.calivar.com>
 
        * include/network.h: Added include of pkgconf/io_eth_drivers.h
Index: net/common//current/src/dhcp_prot.c
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/common/current/src/dhcp_prot.c,v
retrieving revision 1.7
diff -u -r1.7 dhcp_prot.c
--- net/common//current/src/dhcp_prot.c 12 Jan 2003 04:53:28 -0000      1.7
+++ net/common//current/src/dhcp_prot.c 2 Apr 2003 08:34:13 -0000
@@ -1303,21 +1303,22 @@
 #ifdef INET6
     {
       int s6;
-    
+      struct if_laddrreq iflr;
+      
       s6 = socket(AF_INET6, SOCK_DGRAM, 0);
       if (s6 < 0) {
         perror("socket AF_INET6");
         return false;
       }
       // Now delete the ipv6 addr
-      strcpy(ifr.ifr_name, intf);
-      if (ioctl(s6, SIOCGLIFADDR, &ifr)) {
+      strcpy(iflr.iflr_name, intf);
+      if (ioctl(s6, SIOCGLIFADDR, &iflr)) {
        perror("SIOCGIFADDR_IN6 1");
        return false;
       }
       
-      strcpy(ifr.ifr_name, intf);
-      if (ioctl(s6, SIOCDLIFADDR, &ifr)) { /* delete IF addr */
+      strcpy(iflr.iflr_name, intf);
+      if (ioctl(s6, SIOCDLIFADDR, &iflr)) { /* delete IF addr */
         perror("SIOCDIFADDR_IN61");
       }
       close(s6);

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss



More information about the Ecos-discuss mailing list