Commit 638e628a authored by Sjur Braendeland's avatar Sjur Braendeland Committed by David S. Miller

caif: Bugfix - handle mem-allocation failures

Discovered bugs when injecting slab allocation failures.
Add checks on all memory allocation.
Signed-off-by: default avatarSjur Braendeland <sjur.brandeland@stericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7aecf494
...@@ -238,6 +238,7 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len) ...@@ -238,6 +238,7 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
struct sk_buff *lastskb; struct sk_buff *lastskb;
u8 *to; u8 *to;
const u8 *data = data2; const u8 *data = data2;
int ret;
if (unlikely(is_erronous(pkt))) if (unlikely(is_erronous(pkt)))
return -EPROTO; return -EPROTO;
if (unlikely(skb_headroom(skb) < len)) { if (unlikely(skb_headroom(skb) < len)) {
...@@ -246,9 +247,10 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len) ...@@ -246,9 +247,10 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
} }
/* Make sure data is writable */ /* Make sure data is writable */
if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) { ret = skb_cow_data(skb, 0, &lastskb);
if (unlikely(ret < 0)) {
PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n"); PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n");
return -EPROTO; return ret;
} }
to = skb_push(skb, len); to = skb_push(skb, len);
...@@ -316,6 +318,8 @@ EXPORT_SYMBOL(cfpkt_setlen); ...@@ -316,6 +318,8 @@ EXPORT_SYMBOL(cfpkt_setlen);
struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len) struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len)
{ {
struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX); struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
if (!pkt)
return NULL;
if (unlikely(data != NULL)) if (unlikely(data != NULL))
cfpkt_add_body(pkt, data, len); cfpkt_add_body(pkt, data, len);
return pkt; return pkt;
...@@ -344,12 +348,13 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, ...@@ -344,12 +348,13 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
if (dst->tail + neededtailspace > dst->end) { if (dst->tail + neededtailspace > dst->end) {
/* Create a dumplicate of 'dst' with more tail space */ /* Create a dumplicate of 'dst' with more tail space */
struct cfpkt *tmppkt;
dstlen = skb_headlen(dst); dstlen = skb_headlen(dst);
createlen = dstlen + neededtailspace; createlen = dstlen + neededtailspace;
tmp = pkt_to_skb( tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX);
cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX)); if (tmppkt == NULL)
if (!tmp)
return NULL; return NULL;
tmp = pkt_to_skb(tmppkt);
skb_set_tail_pointer(tmp, dstlen); skb_set_tail_pointer(tmp, dstlen);
tmp->len = dstlen; tmp->len = dstlen;
memcpy(tmp->data, dst->data, dstlen); memcpy(tmp->data, dst->data, dstlen);
...@@ -368,6 +373,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) ...@@ -368,6 +373,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
{ {
struct sk_buff *skb2; struct sk_buff *skb2;
struct sk_buff *skb = pkt_to_skb(pkt); struct sk_buff *skb = pkt_to_skb(pkt);
struct cfpkt *tmppkt;
u8 *split = skb->data + pos; u8 *split = skb->data + pos;
u16 len2nd = skb_tail_pointer(skb) - split; u16 len2nd = skb_tail_pointer(skb) - split;
...@@ -381,9 +387,12 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) ...@@ -381,9 +387,12 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
} }
/* Create a new packet for the second part of the data */ /* Create a new packet for the second part of the data */
skb2 = pkt_to_skb( tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX, PKT_PREFIX);
PKT_PREFIX)); if (tmppkt == NULL)
return NULL;
skb2 = pkt_to_skb(tmppkt);
if (skb2 == NULL) if (skb2 == NULL)
return NULL; return NULL;
......
...@@ -67,6 +67,8 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt) ...@@ -67,6 +67,8 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
layr->incomplete_frm = layr->incomplete_frm =
cfpkt_append(layr->incomplete_frm, newpkt, expectlen); cfpkt_append(layr->incomplete_frm, newpkt, expectlen);
pkt = layr->incomplete_frm; pkt = layr->incomplete_frm;
if (pkt == NULL)
return -ENOMEM;
} else { } else {
pkt = newpkt; pkt = newpkt;
} }
...@@ -154,7 +156,6 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt) ...@@ -154,7 +156,6 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
if (layr->usestx) { if (layr->usestx) {
if (tail_pkt != NULL) if (tail_pkt != NULL)
pkt = cfpkt_append(pkt, tail_pkt, 0); pkt = cfpkt_append(pkt, tail_pkt, 0);
/* Start search for next STX if frame failed */ /* Start search for next STX if frame failed */
continue; continue;
} else { } else {
......
...@@ -123,6 +123,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) ...@@ -123,6 +123,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
struct caif_payload_info *info; struct caif_payload_info *info;
u8 flow_off = SRVL_FLOW_OFF; u8 flow_off = SRVL_FLOW_OFF;
pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE);
if (!pkt) {
pr_warning("CAIF: %s(): Out of memory\n",
__func__);
return -ENOMEM;
}
if (cfpkt_add_head(pkt, &flow_off, 1) < 0) { if (cfpkt_add_head(pkt, &flow_off, 1) < 0) {
pr_err("CAIF: %s(): Packet is erroneous!\n", pr_err("CAIF: %s(): Packet is erroneous!\n",
__func__); __func__);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment