[CFR] if_xl.c and if.c null pointer dereferences

Peter Pentchev roam at ringlet.net
Mon Jul 26 12:13:48 PDT 2004


Hi,

A couple of days ago I was handed a new machine with a 3Com 905B card.
Before remembering the PNP OS option in the BIOS, I stumbled across a
couple of null pointer dereferences leading to kernel panics when
FreeBSD 4.10-STABLE could not map the card's resources and attempted to
"clean up" the driver state before it had enough state to begin with.

Attached are two patches, one to if_xl.c and one to if.c, which avoid
"cleaning up" data at pointers that have not been initialized yet.
Although this will not happen in normal operation, there's no need for
the kernel to panic instead of simply reporting that it could not get
the PCI resources it needs :)

G'luck,
Peter

-- 
Peter Pentchev	roam at ringlet.net    roam at cnsys.bg    roam at FreeBSD.org
PGP key:	http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint	FDBA FD79 C26F 3C51 C95E  DF9E ED18 B68D 1619 4553
If this sentence were in Chinese, it would say something else.
-------------- next part --------------
Index: src/sys/net/if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.195
diff -u -r1.195 if.c
--- src/sys/net/if.c	22 Jun 2004 20:13:25 -0000	1.195
+++ src/sys/net/if.c	9 Jul 2004 14:27:49 -0000
@@ -516,6 +516,8 @@
 	int s;
 	int i;
 	struct domain *dp;
+ 	struct ifnet *iter;
+ 	int found;
 
 	EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
 	/*
@@ -582,9 +584,11 @@
 
 
 	/* We can now free link ifaddr. */
-	ifa = TAILQ_FIRST(&ifp->if_addrhead);
-	TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
-	IFAFREE(ifa);
+	if (!TAILQ_EMPTY(&ifp->if_addrhead)) {
+		ifa = TAILQ_FIRST(&ifp->if_addrhead);
+		TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
+		IFAFREE(ifa);
+	}
 
 	/*
 	 * Delete all remaining routes using this interface
@@ -616,7 +620,14 @@
 #endif /* MAC */
 	KNOTE(&ifp->if_klist, NOTE_EXIT);
 	IFNET_WLOCK();
-	TAILQ_REMOVE(&ifnet, ifp, if_link);
+ 	found = 0;
+ 	TAILQ_FOREACH(iter, &ifnet, if_link)
+ 		if (iter == ifp) {
+ 			found = 1;
+ 			break;
+ 		}
+ 	if (found)
+ 		TAILQ_REMOVE(&ifnet, ifp, if_link);
 	IFNET_WUNLOCK();
 	mtx_destroy(&ifp->if_snd.ifq_mtx);
 	IF_AFDATA_DESTROY(ifp);
-------------- next part --------------
Index: src/sys/pci/if_xl.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_xl.c,v
retrieving revision 1.178
diff -u -r1.178 if_xl.c
--- src/sys/pci/if_xl.c	9 Jul 2004 02:28:23 -0000	1.178
+++ src/sys/pci/if_xl.c	9 Jul 2004 14:26:45 -0000
@@ -3169,7 +3169,8 @@
 			sc->xl_cdata.xl_rx_chain[i].xl_mbuf = NULL;
 		}
 	}
-	bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
+	if (sc->xl_ldata.xl_rx_list != NULL)
+		bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
 	/*
 	 * Free the TX list buffers.
 	 */
@@ -3183,7 +3184,8 @@
 			sc->xl_cdata.xl_tx_chain[i].xl_mbuf = NULL;
 		}
 	}
-	bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
+	if (sc->xl_ldata.xl_tx_list != NULL)
+		bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
 
 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-net/attachments/20040726/21b727e1/attachment.bin


More information about the freebsd-net mailing list