diff options
author | Jiri Slaby <jslaby@suse.cz> | 2010-10-10 19:26:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-11 14:05:43 -0400 |
commit | 0aa7deadffd8b596983a3abe29a218b4c5f43301 (patch) | |
tree | 0f741572d7f370e17bd3e504a879b57a637b74e4 | |
parent | ec622ab072e95cf96e78ab4d39d4eea874518c80 (diff) |
NET: wimax, fix use after free
Stanse found that i2400m_rx frees skb, but still uses skb->len even
though it has skb_len defined. So use skb_len properly in the code.
And also define it unsinged int rather than size_t to solve
compilation warnings.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
Cc: linux-wimax@intel.com
Acked-by: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/wimax/i2400m/rx.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 8cc9e319f435..1737d1488b35 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c | |||
@@ -1244,16 +1244,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1244 | int i, result; | 1244 | int i, result; |
1245 | struct device *dev = i2400m_dev(i2400m); | 1245 | struct device *dev = i2400m_dev(i2400m); |
1246 | const struct i2400m_msg_hdr *msg_hdr; | 1246 | const struct i2400m_msg_hdr *msg_hdr; |
1247 | size_t pl_itr, pl_size, skb_len; | 1247 | size_t pl_itr, pl_size; |
1248 | unsigned long flags; | 1248 | unsigned long flags; |
1249 | unsigned num_pls, single_last; | 1249 | unsigned num_pls, single_last, skb_len; |
1250 | 1250 | ||
1251 | skb_len = skb->len; | 1251 | skb_len = skb->len; |
1252 | d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n", | 1252 | d_fnstart(4, dev, "(i2400m %p skb %p [size %u])\n", |
1253 | i2400m, skb, skb_len); | 1253 | i2400m, skb, skb_len); |
1254 | result = -EIO; | 1254 | result = -EIO; |
1255 | msg_hdr = (void *) skb->data; | 1255 | msg_hdr = (void *) skb->data; |
1256 | result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb->len); | 1256 | result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb_len); |
1257 | if (result < 0) | 1257 | if (result < 0) |
1258 | goto error_msg_hdr_check; | 1258 | goto error_msg_hdr_check; |
1259 | result = -EIO; | 1259 | result = -EIO; |
@@ -1261,10 +1261,10 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1261 | pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ | 1261 | pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ |
1262 | num_pls * sizeof(msg_hdr->pld[0]); | 1262 | num_pls * sizeof(msg_hdr->pld[0]); |
1263 | pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN); | 1263 | pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN); |
1264 | if (pl_itr > skb->len) { /* got all the payload descriptors? */ | 1264 | if (pl_itr > skb_len) { /* got all the payload descriptors? */ |
1265 | dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " | 1265 | dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " |
1266 | "%u payload descriptors (%zu each, total %zu)\n", | 1266 | "%u payload descriptors (%zu each, total %zu)\n", |
1267 | skb->len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr); | 1267 | skb_len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr); |
1268 | goto error_pl_descr_short; | 1268 | goto error_pl_descr_short; |
1269 | } | 1269 | } |
1270 | /* Walk each payload payload--check we really got it */ | 1270 | /* Walk each payload payload--check we really got it */ |
@@ -1272,7 +1272,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1272 | /* work around old gcc warnings */ | 1272 | /* work around old gcc warnings */ |
1273 | pl_size = i2400m_pld_size(&msg_hdr->pld[i]); | 1273 | pl_size = i2400m_pld_size(&msg_hdr->pld[i]); |
1274 | result = i2400m_rx_pl_descr_check(i2400m, &msg_hdr->pld[i], | 1274 | result = i2400m_rx_pl_descr_check(i2400m, &msg_hdr->pld[i], |
1275 | pl_itr, skb->len); | 1275 | pl_itr, skb_len); |
1276 | if (result < 0) | 1276 | if (result < 0) |
1277 | goto error_pl_descr_check; | 1277 | goto error_pl_descr_check; |
1278 | single_last = num_pls == 1 || i == num_pls - 1; | 1278 | single_last = num_pls == 1 || i == num_pls - 1; |
@@ -1290,16 +1290,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1290 | if (i < i2400m->rx_pl_min) | 1290 | if (i < i2400m->rx_pl_min) |
1291 | i2400m->rx_pl_min = i; | 1291 | i2400m->rx_pl_min = i; |
1292 | i2400m->rx_num++; | 1292 | i2400m->rx_num++; |
1293 | i2400m->rx_size_acc += skb->len; | 1293 | i2400m->rx_size_acc += skb_len; |
1294 | if (skb->len < i2400m->rx_size_min) | 1294 | if (skb_len < i2400m->rx_size_min) |
1295 | i2400m->rx_size_min = skb->len; | 1295 | i2400m->rx_size_min = skb_len; |
1296 | if (skb->len > i2400m->rx_size_max) | 1296 | if (skb_len > i2400m->rx_size_max) |
1297 | i2400m->rx_size_max = skb->len; | 1297 | i2400m->rx_size_max = skb_len; |
1298 | spin_unlock_irqrestore(&i2400m->rx_lock, flags); | 1298 | spin_unlock_irqrestore(&i2400m->rx_lock, flags); |
1299 | error_pl_descr_check: | 1299 | error_pl_descr_check: |
1300 | error_pl_descr_short: | 1300 | error_pl_descr_short: |
1301 | error_msg_hdr_check: | 1301 | error_msg_hdr_check: |
1302 | d_fnend(4, dev, "(i2400m %p skb %p [size %zu]) = %d\n", | 1302 | d_fnend(4, dev, "(i2400m %p skb %p [size %u]) = %d\n", |
1303 | i2400m, skb, skb_len, result); | 1303 | i2400m, skb, skb_len, result); |
1304 | return result; | 1304 | return result; |
1305 | } | 1305 | } |