madwifi: fix some potential null pointer derefs with wds
[openwrt-10.03/.git] / package / madwifi / patches / 441-fix_ibss_node_handling.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -6641,10 +6641,8 @@ static void
4  ath_recv_mgmt(struct ieee80211vap * vap, struct ieee80211_node *ni_or_null,
5         struct sk_buff *skb, int subtype, int rssi, u_int64_t rtsf)
6  {
7 +       const struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
8         struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);
9 -#ifdef AR_DEBUG
10 -        struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
11 -#endif
12         struct ieee80211_node * ni = ni_or_null;
13         u_int64_t hw_tsf, beacon_tsf;
14         u_int32_t hw_tu, beacon_tu, intval;
15 @@ -6686,7 +6684,7 @@ ath_recv_mgmt(struct ieee80211vap * vap,
16                 }
17                 if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
18                                 (sc->sc_opmode == HAL_M_HOSTAP) &&
19 -                               IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
20 +                               IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) {
21                         /* In this mode, we drive the HAL in HOSTAP mode. Hence
22                          * we do the IBSS merging in software. Also do not merge
23                          * if the difference it too small. Otherwise we are playing
24 --- a/net80211/ieee80211_input.c
25 +++ b/net80211/ieee80211_input.c
26 @@ -311,7 +311,8 @@ ieee80211_input(struct ieee80211vap * va
27                         }
28                         /* Do not try to find a node reference if the packet really did come from the BSS */
29                         if (type == IEEE80211_FC0_TYPE_DATA && ni == vap->iv_bss &&
30 -                                       !IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2)) {
31 +                                       !IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2) &&
32 +                                       IEEE80211_ADDR_EQ(vap->iv_bssid, wh->i_addr3)) {
33                                 /* Try to find sender in local node table. */
34                                 ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
35                                 if (ni == NULL) {
36 @@ -513,6 +514,10 @@ ieee80211_input(struct ieee80211vap * va
37                         break;
38                 case IEEE80211_M_IBSS:
39                 case IEEE80211_M_AHDEMO:
40 +                       /* ignore foreign data frames */
41 +                       if (ni == vap->iv_bss)
42 +                               goto out;
43 +
44                         if (dir != IEEE80211_FC1_DIR_NODS) {
45                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
46                                         wh, "data", "invalid dir 0x%x", dir);
47 @@ -3558,6 +3563,11 @@ ieee80211_recv_mgmt(struct ieee80211vap 
48                         } else if ((vap->iv_opmode == IEEE80211_M_WDS) && vap->iv_wdsnode) {
49                                 found = 1;
50                                 ni = ni_or_null = vap->iv_wdsnode;
51 +                       } else if (vap->iv_opmode == IEEE80211_M_IBSS) {
52 +                               ni_or_null = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
53 +                               if (ni_or_null)
54 +                                       ni = ni_or_null;
55 +                               found = 1;
56                         }
57                         IEEE80211_UNLOCK_IRQ(vap->iv_ic);
58  
59 @@ -3686,19 +3696,8 @@ ieee80211_recv_mgmt(struct ieee80211vap 
60                         vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/
61                         return;
62                 }
63 -               if (ni == vap->iv_bss) {
64 -                       if (vap->iv_opmode == IEEE80211_M_IBSS) {
65 -                               /*
66 -                                * XXX Cannot tell if the sender is operating
67 -                                * in ibss mode.  But we need a new node to
68 -                                * send the response so blindly add them to the
69 -                                * neighbor table.
70 -                                */
71 -                               ni = ieee80211_fakeup_adhoc_node(vap,
72 -                                       wh->i_addr2);
73 -                       } else {
74 -                               ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
75 -                       }
76 +               if (ni == vap->iv_bss && vap->iv_opmode != IEEE80211_M_IBSS) {
77 +                       ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
78                         if (ni == NULL)
79                                 return;
80                         allocbs = 1;
81 --- a/net80211/ieee80211_node.c
82 +++ b/net80211/ieee80211_node.c
83 @@ -601,6 +601,8 @@ ieee80211_ibss_merge(struct ieee80211_no
84                 ic->ic_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long",
85                 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long",
86                 ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "");
87 +       if (!IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bssid))
88 +               ieee80211_node_table_reset(&vap->iv_ic->ic_sta, vap);
89         return ieee80211_sta_join1(ieee80211_ref_node(ni));
90  }
91  EXPORT_SYMBOL(ieee80211_ibss_merge);