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>
