Date: Sat, 21 Jan 2006 02:29:00 -0800 (PST) From: Seth Kingsley <sethk@meowfishies.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/92091: [patch] IP address hash corruption bug Message-ID: <20060121102900.05CC3DA8C0@toxic.magnesium.net> Resent-Message-ID: <200601211030.k0LAU32Q088569@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 92091 >Category: kern >Synopsis: [patch] IP address hash corruption bug >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Jan 21 10:30:03 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Seth Kingsley >Release: FreeBSD 5.4-RELEASE i386 >Organization: >Environment: System: FreeBSD neko.home.meowfishies.com 5.4-RELEASE FreeBSD 5.4-RELEASE #1: Sat Jan 14 22:37:52 UTC 2006 sethk@neko.home.meowfishies.com:/usr/src/sys/i386/compile/GENERIC i386 >Description: You can cause a panic (page fault) by supplying a non AF_INET address as parameter to SIOCSIFADDR. The command will fail, removing the temporary address from the IP hash, which it was never added to. >How-To-Repeat: #include <sys/types.h> #include <sys/socket.h> #include <sys/sockio.h> #include <net/if.h> #include <netinet/in.h> #include <stdio.h> #include <sysexits.h> #include <err.h> int main(int ac, char *av[]) { const char *ifname; int sfd; struct ifreq ifr; register int i; if (ac != 2) { fprintf(stderr, "usage: %s <ifname>\n", getprogname()); return EX_USAGE; } if ((sfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) err(EX_OSERR, "create socket"); bzero(&ifr, sizeof(ifr)); strlcpy(ifr.ifr_name, av[1], sizeof(ifr.ifr_name)); ifr.ifr_addr.sa_len = 0; ifr.ifr_addr.sa_family = AF_MAX; for (i = 0; i < 2; ++i) if (ioctl(sfd, SIOCSIFADDR, &ifr) == -1) err(EX_OSERR, "SIOCSIFADDR"); close(sfd); return EX_OK; } >Fix: Only remove the temporary in_ifaddr structure from the hash if it is actually an AF_INET address: --- /sys/netinet/in.c.orig Sun Jan 22 02:16:39 2006 +++ /sys/netinet/in.c Sun Jan 22 02:17:14 2006 @@ -466,7 +466,8 @@ s = splnet(); TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link); - LIST_REMOVE(ia, ia_hash); + if (ia->ia_addr.sin_family == AF_INET) + LIST_REMOVE(ia, ia_hash); IFAFREE(&ia->ia_ifa); splx(s); >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060121102900.05CC3DA8C0>