From owner-freebsd-hackers@FreeBSD.ORG Tue Mar 8 22:08:13 2005 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2AD2216A4CE for ; Tue, 8 Mar 2005 22:08:13 +0000 (GMT) Received: from md2.swissinfo.org (md2.swissinfo.org [146.159.4.93]) by mx1.FreeBSD.org (Postfix) with ESMTP id A37B743D58 for ; Tue, 8 Mar 2005 22:08:10 +0000 (GMT) (envelope-from sebastien.b@swissinfo.org) Received: from mail.swissinfo.org ([194.6.181.33]) by md2.swissinfo.org (phad2.swissinfo.org [146.159.6.10]) (MDaemon.PRO.v7.2.1.R) with ESMTP id 11-md50000294068.msg for ; Tue, 08 Mar 2005 23:08:01 +0100 Received: from [10.0.1.1] (82.231.254.101) by mail.swissinfo.org (7.0.020) (authenticated as sebastien.b) id 4153942002775114 for freebsd-hackers@freebsd.org; Tue, 8 Mar 2005 23:07:56 +0100 From: Sebastien B To: freebsd-hackers@freebsd.org Date: Tue, 8 Mar 2005 23:11:11 +0100 User-Agent: KMail/1.7 MIME-Version: 1.0 Content-Disposition: inline Message-Id: <200503082311.12538.sebastien.b@swissinfo.org> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Spam-Processed: phad2.swissinfo.org, Tue, 08 Mar 2005 23:08:01 +0100 (not processed: spam filter disabled) X-MDRemoteIP: 194.6.181.33 X-Return-Path: sebastien.b@swissinfo.org X-MDaemon-Deliver-To: freebsd-hackers@freebsd.org X-MDAV-Processed: phad2.swissinfo.org, Tue, 08 Mar 2005 23:08:04 +0100 Subject: ieee80211_input() problems X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Mar 2005 22:08:13 -0000 Hello, I'm in real trouble with that function :( I have the following code, "frame" is a char pointer to data corresponding to the 802.11 frame and "frame_size" is its length in bytes : if(ic->ic_opmode != IEEE80211_M_STA) { struct ieee80211_frame_min *wh = (struct ieee80211_frame_min *)frame; //data_head; ni = ieee80211_find_node(ic, wh->i_addr2); if(ni == NULL) ni = ieee80211_ref_node(ic->ic_bss); } else ni = ieee80211_ref_node(ic->ic_bss); /* Put the data into an mbuf and pass it to the upper layers */ if(frame_size > MCLBYTES) { p54u_err("Frame too large for mbuf cluster"); return; } MGETHDR(buf, M_DONTWAIT, MT_DATA); if(buf == NULL) { p54u_err("mbuf allocation failed"); return; } if(frame_size > MHLEN) { p54u_dbg("allocating mbuf cluster"); MCLGET(buf, M_DONTWAIT); if((buf->m_flags & M_EXT) == 0) { p54u_err("mbuf cluster allocation failed"); m_freem(buf); return; } } buffer = mtod(buf, char *); memcpy(buffer, frame, frame_size); buf->m_pkthdr.rcvif = &sc->sc_if; buf->m_pkthdr.len = buf->m_len = frame_size; ieee80211_input(&sc->sc_if, buf, ni, data_head->signal_strength, le32toh(data_head->timestamp)); /* * Reclaim node reference. */ if (ni == ic->ic_bss) ieee80211_unref_node(&ni); else ieee80211_free_node(ic, ni); With this, the kernel panics every time a frame is received :( The kernel messages are : Fatal trap 12: page fault while in kernel mode fault virtual address = 0x23 fault code = supervisor read, page not present instruction pointer = 0x8:0xc07c3d82 stack pointer = 0x10:0xd4cf9c20 frame pointer = 0x10:0xd4cf9c60 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, def32 1, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = 493 (swi7: int_ack++) It suggests that software is attempting to read from an invalid memory location. - I tried commenting out ieee80211_input. No more crashes, but the function's useless... - In case there was not enough space in mbuf (thus ieee80211_input() would try to access memory which doesn't belong to us), I tried reading frame_size bytes from the adress pointed to by "buffer". No crash. Moreover, the mbuf data seems consistent, I can see the ESSID in it (anyway I think that ieee80211_input() shouldn't crash because of an unconsistent frame ; otherwise someone could crash all computers around by sending forged 802.11 frames...) - I tried with and without referencing ic->ic_bss. No effect. - Making frame_size deliberately too small before the call to ieee80211_input() makes the kernel not crash. So ieee80211_input() seems to ignore the packet in case it's too small, it seems to read correctly the size field (I tried 10 bytes). - The data_head->signal_strength and data_head->timestamp dereferencings are not responsible for the kernel panic, and they return the correct data. I hope someone can help, I just can't figure out what's going wrong after hours of debugging, and constantly rebooting is really tedious. Thanks, Sebastien