diff options
author | guido <guido@FreeBSD.org> | 2000-02-28 19:30:25 +0000 |
---|---|---|
committer | guido <guido@FreeBSD.org> | 2000-02-28 19:30:25 +0000 |
commit | 0dbc45d7e8fc7d4b0bed80760c194b8fe4a2261a (patch) | |
tree | b3493d21163bc645befcc5c98fc5f056fa35bbdb /sys/net/if.c | |
parent | b401a071dd1a505c31e71c29311572a0ae6c2118 (diff) | |
download | FreeBSD-src-0dbc45d7e8fc7d4b0bed80760c194b8fe4a2261a.zip FreeBSD-src-0dbc45d7e8fc7d4b0bed80760c194b8fe4a2261a.tar.gz |
This fixes a problem where the SIOCGIFCONF ioctl goes wrong. This
is triggered when qmail is used with INET6 enabled. The bug
manifests itself in that the space variable can become negative
and that in the comparison in the guards of the 2 loops, this was
not noticed because sizeof() returns an unsigned and thus the signed
variable gets promoted to unsigned. I decided not to make space
unsigned because I think we should guard against this from happening.
Thus panic() in case space becomes negative.
Approved by: jkh
Diffstat (limited to 'sys/net/if.c')
-rw-r--r-- | sys/net/if.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 6a47951c..6c105b6 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1056,6 +1056,7 @@ ifconf(cmd, data) "%s%d", ifp->if_name, ifp->if_unit); if(ifnlen + 1 > sizeof ifr.ifr_name) { error = ENAMETOOLONG; + break; } else { strcpy(ifr.ifr_name, workbuf); } @@ -1085,6 +1086,8 @@ ifconf(cmd, data) sizeof (ifr)); ifrp++; } else { + if (space < sa->sa_len - sizeof(*sa)) + break; space -= sa->sa_len - sizeof(*sa); if (space < sizeof (ifr)) break; @@ -1100,15 +1103,20 @@ ifconf(cmd, data) break; space -= sizeof (ifr); } + if (error) + break; if (!addrs) { bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr)); if (error) break; - space -= sizeof (ifr), ifrp++; + space -= sizeof (ifr); + ifrp++; } } + if (space < 0) + panic("ifconf: space < 0"); ifc->ifc_len -= space; return (error); } |