Date: Tue, 8 Mar 2005 23:11:11 +0100 From: Sebastien B <sebastien.b@swissinfo.org> To: freebsd-hackers@freebsd.org Subject: ieee80211_input() problems Message-ID: <200503082311.12538.sebastien.b@swissinfo.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200503082311.12538.sebastien.b>