aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorAndy Green <andy@warmcat.com>2007-07-27 09:43:24 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:47:41 -0400
commit9b8a74e3482f9fc077a88c13fa0ceca8feb0b772 (patch)
tree0e55e12e233d534de8df14854cdf36ae8391fc5d /net/mac80211/tx.c
parentdfe6e81deaa79c85086c0cc8d85b229e444ab97f (diff)
[MAC80211]: Improve sanity checks on injected packets
Michael Wu noticed that the skb length checking is not taken care of enough when a packet is presented on the Monitor interface for injection. This patch improves the sanity checking and removes fake offsets placed into the skb network and transport header. Signed-off-by: Andy Green <andy@warmcat.com> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 36761c7139bc..457166889cc7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1270,46 +1270,54 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1270 struct ieee80211_tx_packet_data *pkt_data; 1270 struct ieee80211_tx_packet_data *pkt_data;
1271 struct ieee80211_radiotap_header *prthdr = 1271 struct ieee80211_radiotap_header *prthdr =
1272 (struct ieee80211_radiotap_header *)skb->data; 1272 (struct ieee80211_radiotap_header *)skb->data;
1273 u16 len; 1273 u16 len_rthdr;
1274 1274
1275 /* 1275 /* check for not even having the fixed radiotap header part */
1276 * there must be a radiotap header at the 1276 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
1277 * start in this case 1277 goto fail; /* too short to be possibly valid */
1278 */ 1278
1279 if (unlikely(prthdr->it_version)) { 1279 /* is it a header version we can trust to find length from? */
1280 /* only version 0 is supported */ 1280 if (unlikely(prthdr->it_version))
1281 dev_kfree_skb(skb); 1281 goto fail; /* only version 0 is supported */
1282 return NETDEV_TX_OK; 1282
1283 } 1283 /* then there must be a radiotap header with a length we can use */
1284 len_rthdr = ieee80211_get_radiotap_len(skb->data);
1285
1286 /* does the skb contain enough to deliver on the alleged length? */
1287 if (unlikely(skb->len < len_rthdr))
1288 goto fail; /* skb too short for claimed rt header extent */
1284 1289
1285 skb->dev = local->mdev; 1290 skb->dev = local->mdev;
1286 1291
1287 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; 1292 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1288 memset(pkt_data, 0, sizeof(*pkt_data)); 1293 memset(pkt_data, 0, sizeof(*pkt_data));
1294 /* needed because we set skb device to master */
1289 pkt_data->ifindex = dev->ifindex; 1295 pkt_data->ifindex = dev->ifindex;
1296
1290 pkt_data->mgmt_iface = 0; 1297 pkt_data->mgmt_iface = 0;
1291 pkt_data->do_not_encrypt = 1; 1298 pkt_data->do_not_encrypt = 1;
1292 1299
1293 /* above needed because we set skb device to master */
1294
1295 /* 1300 /*
1296 * fix up the pointers accounting for the radiotap 1301 * fix up the pointers accounting for the radiotap
1297 * header still being in there. We are being given 1302 * header still being in there. We are being given
1298 * a precooked IEEE80211 header so no need for 1303 * a precooked IEEE80211 header so no need for
1299 * normal processing 1304 * normal processing
1300 */ 1305 */
1301 len = le16_to_cpu(get_unaligned(&prthdr->it_len)); 1306 skb_set_mac_header(skb, len_rthdr);
1302 skb_set_mac_header(skb, len);
1303 skb_set_network_header(skb, len + sizeof(struct ieee80211_hdr));
1304 skb_set_transport_header(skb, len + sizeof(struct ieee80211_hdr));
1305
1306 /* 1307 /*
1307 * pass the radiotap header up to 1308 * these are just fixed to the end of the rt area since we
1308 * the next stage intact 1309 * don't have any better information and at this point, nobody cares
1309 */ 1310 */
1310 dev_queue_xmit(skb); 1311 skb_set_network_header(skb, len_rthdr);
1312 skb_set_transport_header(skb, len_rthdr);
1311 1313
1314 /* pass the radiotap header up to the next stage intact */
1315 dev_queue_xmit(skb);
1312 return NETDEV_TX_OK; 1316 return NETDEV_TX_OK;
1317
1318fail:
1319 dev_kfree_skb(skb);
1320 return NETDEV_TX_OK; /* meaning, we dealt with the skb */
1313} 1321}
1314 1322
1315/** 1323/**