From b15829ba5e82b919513f8ac70e97b4e474fae641 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Tue, 23 Sep 2014 16:38:02 -0700 Subject: [PATCH] NFC: digital: Fix potential skb leaks in NFC-DEP code When digital_in_send_cmd() or digital_tg_send_cmd() fail, they do not free the skb that was passed to them so the routine that allocated the skb should free it. Currently, there are several routines in the NFC-DEP code that don't do this so make them. Reviewed-by: Thierry Escande Tested-by: Thierry Escande Signed-off-by: Mark A. Greer Signed-off-by: Samuel Ortiz --- net/nfc/digital_dep.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c index b60aa35c074f..70fcce03e8a9 100644 --- a/net/nfc/digital_dep.c +++ b/net/nfc/digital_dep.c @@ -198,6 +198,7 @@ static int digital_in_send_psl_req(struct nfc_digital_dev *ddev, { struct sk_buff *skb; struct digital_psl_req *psl_req; + int rc; skb = digital_skb_alloc(ddev, sizeof(*psl_req)); if (!skb) @@ -217,8 +218,12 @@ static int digital_in_send_psl_req(struct nfc_digital_dev *ddev, ddev->skb_add_crc(skb); - return digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res, - target); + rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res, + target); + if (rc) + kfree_skb(skb); + + return rc; } static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg, @@ -286,6 +291,7 @@ int digital_in_send_atr_req(struct nfc_digital_dev *ddev, struct sk_buff *skb; struct digital_atr_req *atr_req; uint size; + int rc; size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len; @@ -325,8 +331,12 @@ int digital_in_send_atr_req(struct nfc_digital_dev *ddev, ddev->skb_add_crc(skb); - return digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, - target); + rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, + target); + if (rc) + kfree_skb(skb); + + return rc; } static int digital_in_send_rtox(struct nfc_digital_dev *ddev, @@ -357,6 +367,8 @@ static int digital_in_send_rtox(struct nfc_digital_dev *ddev, rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, data_exch); + if (rc) + kfree_skb(skb); return rc; } @@ -634,7 +646,6 @@ static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did, rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete, (void *)(unsigned long)rf_tech); - if (rc) kfree_skb(skb); @@ -758,10 +769,8 @@ static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev, rc = digital_tg_send_cmd(ddev, skb, 999, digital_tg_send_atr_res_complete, NULL); - if (rc) { + if (rc) kfree_skb(skb); - return rc; - } return rc; }