diff options
author | Raju Rangoju <rajur@chelsio.com> | 2017-05-15 02:40:39 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-06-01 17:01:28 -0400 |
commit | 1dad0ebeea1cd890b8892523f736916e245b0aef (patch) | |
tree | f3567965cb92ae062852fe025bd32c338d7588f6 | |
parent | f863de7de34025ee536cb3cc382bfc3cafaa9f0a (diff) |
RDMA/iw_cxgb4: Avoid touch after free error in ARP failure handlers
The patch 761e19a504af (RDMA/iw_cxgb4: Handle return value of
c4iw_ofld_send() in abort_arp_failure()) from May 6, 2016
leads to the following static checker warning:
drivers/infiniband/hw/cxgb4/cm.c:575 abort_arp_failure()
warn: passing freed memory 'skb'
Also fixes skb leak when l2t resolution fails
Fixes: 761e19a504afa55 (RDMA/iw_cxgb4: Handle return value of
c4iw_ofld_send() in abort_arp_failure())
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Raju Rangoju <rajur@chelsio.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index b6fe45924c6e..06b110213e92 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -488,6 +488,7 @@ static int _put_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb) | |||
488 | 488 | ||
489 | ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); | 489 | ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); |
490 | release_ep_resources(ep); | 490 | release_ep_resources(ep); |
491 | kfree_skb(skb); | ||
491 | return 0; | 492 | return 0; |
492 | } | 493 | } |
493 | 494 | ||
@@ -498,6 +499,7 @@ static int _put_pass_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb) | |||
498 | ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); | 499 | ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); |
499 | c4iw_put_ep(&ep->parent_ep->com); | 500 | c4iw_put_ep(&ep->parent_ep->com); |
500 | release_ep_resources(ep); | 501 | release_ep_resources(ep); |
502 | kfree_skb(skb); | ||
501 | return 0; | 503 | return 0; |
502 | } | 504 | } |
503 | 505 | ||
@@ -569,11 +571,13 @@ static void abort_arp_failure(void *handle, struct sk_buff *skb) | |||
569 | 571 | ||
570 | pr_debug("%s rdev %p\n", __func__, rdev); | 572 | pr_debug("%s rdev %p\n", __func__, rdev); |
571 | req->cmd = CPL_ABORT_NO_RST; | 573 | req->cmd = CPL_ABORT_NO_RST; |
574 | skb_get(skb); | ||
572 | ret = c4iw_ofld_send(rdev, skb); | 575 | ret = c4iw_ofld_send(rdev, skb); |
573 | if (ret) { | 576 | if (ret) { |
574 | __state_set(&ep->com, DEAD); | 577 | __state_set(&ep->com, DEAD); |
575 | queue_arp_failure_cpl(ep, skb, FAKE_CPL_PUT_EP_SAFE); | 578 | queue_arp_failure_cpl(ep, skb, FAKE_CPL_PUT_EP_SAFE); |
576 | } | 579 | } else |
580 | kfree_skb(skb); | ||
577 | } | 581 | } |
578 | 582 | ||
579 | static int send_flowc(struct c4iw_ep *ep) | 583 | static int send_flowc(struct c4iw_ep *ep) |