diff options
author | Arik Nemtsov <arik@wizery.com> | 2011-04-26 16:35:40 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-05-02 03:27:25 -0400 |
commit | 34c8e3d2bb901b2920d2a8930c0de82e7fefac76 (patch) | |
tree | 8e0edf55792dea5f28e00d54829ffd95b48f53cd /drivers/net | |
parent | 33437893025aa3c0195b933ac99ef7de924019f4 (diff) |
wl12xx: discard corrupted packets in RX
When packets arrive with a RX descriptor indicating corruption, discard
them.
In general white-list the RX descriptor status to prevent rouge data
from being sent up.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/wl12xx/rx.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index faf5a1d3c2c3..70091035e019 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c | |||
@@ -76,12 +76,15 @@ static void wl1271_rx_status(struct wl1271 *wl, | |||
76 | status->band); | 76 | status->band); |
77 | 77 | ||
78 | if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { | 78 | if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { |
79 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; | 79 | u8 desc_err_code = desc->status & WL1271_RX_DESC_STATUS_MASK; |
80 | 80 | ||
81 | if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL))) | 81 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED | |
82 | status->flag |= RX_FLAG_DECRYPTED; | 82 | RX_FLAG_DECRYPTED; |
83 | if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL)) | 83 | |
84 | if (unlikely(desc_err_code == WL1271_RX_DESC_MIC_FAIL)) { | ||
84 | status->flag |= RX_FLAG_MMIC_ERROR; | 85 | status->flag |= RX_FLAG_MMIC_ERROR; |
86 | wl1271_warning("Michael MIC error"); | ||
87 | } | ||
85 | } | 88 | } |
86 | } | 89 | } |
87 | 90 | ||
@@ -100,6 +103,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
100 | if (unlikely(wl->state == WL1271_STATE_PLT)) | 103 | if (unlikely(wl->state == WL1271_STATE_PLT)) |
101 | return -EINVAL; | 104 | return -EINVAL; |
102 | 105 | ||
106 | /* the data read starts with the descriptor */ | ||
107 | desc = (struct wl1271_rx_descriptor *) data; | ||
108 | |||
109 | switch (desc->status & WL1271_RX_DESC_STATUS_MASK) { | ||
110 | /* discard corrupted packets */ | ||
111 | case WL1271_RX_DESC_DRIVER_RX_Q_FAIL: | ||
112 | case WL1271_RX_DESC_DECRYPT_FAIL: | ||
113 | wl1271_warning("corrupted packet in RX with status: 0x%x", | ||
114 | desc->status & WL1271_RX_DESC_STATUS_MASK); | ||
115 | return -EINVAL; | ||
116 | case WL1271_RX_DESC_SUCCESS: | ||
117 | case WL1271_RX_DESC_MIC_FAIL: | ||
118 | break; | ||
119 | default: | ||
120 | wl1271_error("invalid RX descriptor status: 0x%x", | ||
121 | desc->status & WL1271_RX_DESC_STATUS_MASK); | ||
122 | return -EINVAL; | ||
123 | } | ||
124 | |||
103 | skb = __dev_alloc_skb(length, GFP_KERNEL); | 125 | skb = __dev_alloc_skb(length, GFP_KERNEL); |
104 | if (!skb) { | 126 | if (!skb) { |
105 | wl1271_error("Couldn't allocate RX frame"); | 127 | wl1271_error("Couldn't allocate RX frame"); |
@@ -109,9 +131,6 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
109 | buf = skb_put(skb, length); | 131 | buf = skb_put(skb, length); |
110 | memcpy(buf, data, length); | 132 | memcpy(buf, data, length); |
111 | 133 | ||
112 | /* the data read starts with the descriptor */ | ||
113 | desc = (struct wl1271_rx_descriptor *) buf; | ||
114 | |||
115 | /* now we pull the descriptor out of the buffer */ | 134 | /* now we pull the descriptor out of the buffer */ |
116 | skb_pull(skb, sizeof(*desc)); | 135 | skb_pull(skb, sizeof(*desc)); |
117 | 136 | ||