aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSjur Braendeland <sjur.brandeland@stericsson.com>2010-05-20 22:16:09 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-24 02:57:42 -0400
commit638e628a600a5c542d46dfb06771cf9c229ef5f3 (patch)
tree777d4d2b9aee8a1d4b0ce522bf3957023a9bfb7e
parent7aecf4944f2c05aafb73b4820e469c74b4ec8517 (diff)
caif: Bugfix - handle mem-allocation failures
Discovered bugs when injecting slab allocation failures. Add checks on all memory allocation. Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/caif/cfpkt_skbuff.c25
-rw-r--r--net/caif/cfserl.c3
-rw-r--r--net/caif/cfsrvl.c6
3 files changed, 25 insertions, 9 deletions
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
index 83fff2ff6658..a6fdf899741a 100644
--- a/net/caif/cfpkt_skbuff.c
+++ b/net/caif/cfpkt_skbuff.c
@@ -238,6 +238,7 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
238 struct sk_buff *lastskb; 238 struct sk_buff *lastskb;
239 u8 *to; 239 u8 *to;
240 const u8 *data = data2; 240 const u8 *data = data2;
241 int ret;
241 if (unlikely(is_erronous(pkt))) 242 if (unlikely(is_erronous(pkt)))
242 return -EPROTO; 243 return -EPROTO;
243 if (unlikely(skb_headroom(skb) < len)) { 244 if (unlikely(skb_headroom(skb) < len)) {
@@ -246,9 +247,10 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
246 } 247 }
247 248
248 /* Make sure data is writable */ 249 /* Make sure data is writable */
249 if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) { 250 ret = skb_cow_data(skb, 0, &lastskb);
251 if (unlikely(ret < 0)) {
250 PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n"); 252 PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n");
251 return -EPROTO; 253 return ret;
252 } 254 }
253 255
254 to = skb_push(skb, len); 256 to = skb_push(skb, len);
@@ -316,6 +318,8 @@ EXPORT_SYMBOL(cfpkt_setlen);
316struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len) 318struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len)
317{ 319{
318 struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX); 320 struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
321 if (!pkt)
322 return NULL;
319 if (unlikely(data != NULL)) 323 if (unlikely(data != NULL))
320 cfpkt_add_body(pkt, data, len); 324 cfpkt_add_body(pkt, data, len);
321 return pkt; 325 return pkt;
@@ -344,12 +348,13 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
344 348
345 if (dst->tail + neededtailspace > dst->end) { 349 if (dst->tail + neededtailspace > dst->end) {
346 /* Create a dumplicate of 'dst' with more tail space */ 350 /* Create a dumplicate of 'dst' with more tail space */
351 struct cfpkt *tmppkt;
347 dstlen = skb_headlen(dst); 352 dstlen = skb_headlen(dst);
348 createlen = dstlen + neededtailspace; 353 createlen = dstlen + neededtailspace;
349 tmp = pkt_to_skb( 354 tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX);
350 cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX)); 355 if (tmppkt == NULL)
351 if (!tmp)
352 return NULL; 356 return NULL;
357 tmp = pkt_to_skb(tmppkt);
353 skb_set_tail_pointer(tmp, dstlen); 358 skb_set_tail_pointer(tmp, dstlen);
354 tmp->len = dstlen; 359 tmp->len = dstlen;
355 memcpy(tmp->data, dst->data, dstlen); 360 memcpy(tmp->data, dst->data, dstlen);
@@ -368,6 +373,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
368{ 373{
369 struct sk_buff *skb2; 374 struct sk_buff *skb2;
370 struct sk_buff *skb = pkt_to_skb(pkt); 375 struct sk_buff *skb = pkt_to_skb(pkt);
376 struct cfpkt *tmppkt;
371 u8 *split = skb->data + pos; 377 u8 *split = skb->data + pos;
372 u16 len2nd = skb_tail_pointer(skb) - split; 378 u16 len2nd = skb_tail_pointer(skb) - split;
373 379
@@ -381,9 +387,12 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
381 } 387 }
382 388
383 /* Create a new packet for the second part of the data */ 389 /* Create a new packet for the second part of the data */
384 skb2 = pkt_to_skb( 390 tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
385 cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX, 391 PKT_PREFIX);
386 PKT_PREFIX)); 392 if (tmppkt == NULL)
393 return NULL;
394 skb2 = pkt_to_skb(tmppkt);
395
387 396
388 if (skb2 == NULL) 397 if (skb2 == NULL)
389 return NULL; 398 return NULL;
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
index 06029ea2da2f..cb4325a3dc83 100644
--- a/net/caif/cfserl.c
+++ b/net/caif/cfserl.c
@@ -67,6 +67,8 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
67 layr->incomplete_frm = 67 layr->incomplete_frm =
68 cfpkt_append(layr->incomplete_frm, newpkt, expectlen); 68 cfpkt_append(layr->incomplete_frm, newpkt, expectlen);
69 pkt = layr->incomplete_frm; 69 pkt = layr->incomplete_frm;
70 if (pkt == NULL)
71 return -ENOMEM;
70 } else { 72 } else {
71 pkt = newpkt; 73 pkt = newpkt;
72 } 74 }
@@ -154,7 +156,6 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
154 if (layr->usestx) { 156 if (layr->usestx) {
155 if (tail_pkt != NULL) 157 if (tail_pkt != NULL)
156 pkt = cfpkt_append(pkt, tail_pkt, 0); 158 pkt = cfpkt_append(pkt, tail_pkt, 0);
157
158 /* Start search for next STX if frame failed */ 159 /* Start search for next STX if frame failed */
159 continue; 160 continue;
160 } else { 161 } else {
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c
index aff31f34528f..6e5b7079a684 100644
--- a/net/caif/cfsrvl.c
+++ b/net/caif/cfsrvl.c
@@ -123,6 +123,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
123 struct caif_payload_info *info; 123 struct caif_payload_info *info;
124 u8 flow_off = SRVL_FLOW_OFF; 124 u8 flow_off = SRVL_FLOW_OFF;
125 pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); 125 pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE);
126 if (!pkt) {
127 pr_warning("CAIF: %s(): Out of memory\n",
128 __func__);
129 return -ENOMEM;
130 }
131
126 if (cfpkt_add_head(pkt, &flow_off, 1) < 0) { 132 if (cfpkt_add_head(pkt, &flow_off, 1) < 0) {
127 pr_err("CAIF: %s(): Packet is erroneous!\n", 133 pr_err("CAIF: %s(): Packet is erroneous!\n",
128 __func__); 134 __func__);