Subject: kern/23306: Kernel Segmentation Fault on wireless cards
To: None <gnats-bugs@gnats.netbsd.org>
From: pancake <pancake@phreaker.net>
List: netbsd-bugs
Date: 10/29/2003 17:57:32
>Number: 23306
>Category: kern
>Synopsis: Kernel Segmentation Fault on wireless cards
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Oct 29 18:00:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:
>Release: NetBSD 1.6ZD
>Organization:
>Environment:
System: NetBSD pl2 1.6ZD NetBSD 1.6ZD (PANCAKE_LAPTOP) #1: Sun Oct 26 02:32:21 UTC 2003 root@pl2:/usr/src/sys/arch/i386/compile/PANCAKE_LAPTOP i386
Architecture: i386
Machine: i386
>Description:
NetBSD-current segfaults trying to put the wireless card in some
invalid specific channel mode.
That's because dev/ic/wi.c doesn't check return values of functions
before using it as array pointer. This causes a kernel segfault.
>How-To-Repeat:
To repeat this segfault:
# ifconfig wi0 media DS11 mediaopt ibss
It's NOT exploitable, just segfaultable.
I have a "Lucent wireless card" but I know that this segfaults also
on prism-based, because the last kernel changes on wireless.
a dmesg of my wi0 is:
wi0 at pcmcia0 function 0: Cabletron, RoamAbout 802.11 DS, Version 01.01
wi0: port 0x400-0x43fuhidev0 at uhub0 port 1 configuration 1 interface 0
wi0: using Lucent Technologies, WaveLAN/IEEE
wi0: Lucent Firmware: Station (6.4.1)
wi0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps
>Fix:
Just apply this patch to the official NetBSD kernel tree src.
--- dev/ic/wi.c.orig 2003-10-29 17:02:40.000000000 +0000
+++ dev/ic/wi.c 2003-10-29 17:14:11.000000000 +0000
@@ -104,6 +104,7 @@
#include <machine/bus.h>
+#include <dev/ic/icpreg.h>
#include <dev/ic/wi_ieee.h>
#include <dev/ic/wireg.h>
#include <dev/ic/wivar.h>
@@ -1077,9 +1078,14 @@
if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) {
i = -1;
} else {
- struct ieee80211_rateset *rs =
- &ic->ic_sup_rates[ieee80211_chan2mode(ic,
- ic->ic_bss->ni_chan)];
+ struct ieee80211_rateset *rs = 0;
+ enum ieee80211_phymode phymode =
+ ieee80211_chan2mode(ic,ic->ic_bss->ni_chan);
+
+ if (phymode == ICP_INVALID_CHANNEL)
+ return EINVAL;
+
+ rs = &ic->ic_sup_rates[phymode];
rate = ieee80211_media2rate(ime->ifm_media);
if (rate == 0)
return EINVAL;
>Release-Note:
>Audit-Trail:
>Unformatted: