Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net fix interface address list traversal in if_detach():
details: https://anonhg.NetBSD.org/src/rev/13ab9b710374
branches: trunk
changeset: 555217:13ab9b710374
user: drochner <drochner%NetBSD.org@localhost>
date: Tue Nov 11 20:33:46 2003 +0000
description:
fix interface address list traversal in if_detach():
The code was assuming that interface addresses are removed one-by-one.
With IPv6 and multicasts, removal of one address can remove other
addresses as side effect, which caused accesses of free()d memory.
diffstat:
sys/net/if.c | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)
diffs (58 lines):
diff -r 15b704ca0507 -r 13ab9b710374 sys/net/if.c
--- a/sys/net/if.c Tue Nov 11 20:25:26 2003 +0000
+++ b/sys/net/if.c Tue Nov 11 20:33:46 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.133 2003/11/10 20:03:29 jonathan Exp $ */
+/* $NetBSD: if.c,v 1.134 2003/11/11 20:33:46 drochner Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.133 2003/11/10 20:03:29 jonathan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.134 2003/11/11 20:33:46 drochner Exp $");
#include "opt_inet.h"
@@ -544,7 +544,7 @@
struct ifnet *ifp;
{
struct socket so;
- struct ifaddr *ifa, *next;
+ struct ifaddr *ifa, **ifap;
#ifdef IFAREF_DEBUG
struct ifaddr *last_ifa = NULL;
#endif
@@ -581,8 +581,8 @@
* Rip all the addresses off the interface. This should make
* all of the routes go away.
*/
- for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa; ifa = next) {
- next = TAILQ_NEXT(ifa, ifa_list);
+ ifap = &TAILQ_FIRST(&ifp->if_addrlist); /* XXX abstraction violation */
+ while ((ifa = *ifap)) {
family = ifa->ifa_addr->sa_family;
#ifdef IFAREF_DEBUG
printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
@@ -591,8 +591,10 @@
panic("if_detach: loop detected");
last_ifa = ifa;
#endif
- if (family == AF_LINK)
+ if (family == AF_LINK) {
+ ifap = &TAILQ_NEXT(ifa, ifa_list);
continue;
+ }
dp = pffinddomain(family);
#ifdef DIAGNOSTIC
if (dp == NULL)
@@ -617,6 +619,7 @@
*/
printf("if_detach: WARNING: AF %d not purged\n",
family);
+ TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
}
}
Home |
Main Index |
Thread Index |
Old Index