nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling
authorMartin Faltesek <mfaltesek@google.com>
Tue, 7 Jun 2022 02:57:28 +0000 (21:57 -0500)
committerJakub Kicinski <kuba@kernel.org>
Wed, 8 Jun 2022 17:17:17 +0000 (10:17 -0700)
Error paths do not free previously allocated memory. Add devm_kfree() to
those failure paths.

Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support")
Fixes: 4fbcc1a4cb20 ("nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION")
Cc: stable@vger.kernel.org
Signed-off-by: Martin Faltesek <mfaltesek@google.com>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/nfc/st21nfca/se.c

index 9645777..8e1113c 100644 (file)
@@ -326,22 +326,29 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host,
                transaction->aid_len = skb->data[1];
 
                /* Checking if the length of the AID is valid */
-               if (transaction->aid_len > sizeof(transaction->aid))
+               if (transaction->aid_len > sizeof(transaction->aid)) {
+                       devm_kfree(dev, transaction);
                        return -EINVAL;
+               }
 
                memcpy(transaction->aid, &skb->data[2],
                       transaction->aid_len);
 
                /* Check next byte is PARAMETERS tag (82) */
                if (skb->data[transaction->aid_len + 2] !=
-                   NFC_EVT_TRANSACTION_PARAMS_TAG)
+                   NFC_EVT_TRANSACTION_PARAMS_TAG) {
+                       devm_kfree(dev, transaction);
                        return -EPROTO;
+               }
 
                transaction->params_len = skb->data[transaction->aid_len + 3];
 
                /* Total size is allocated (skb->len - 2) minus fixed array members */
-               if (transaction->params_len > ((skb->len - 2) - sizeof(struct nfc_evt_transaction)))
+               if (transaction->params_len > ((skb->len - 2) -
+                   sizeof(struct nfc_evt_transaction))) {
+                       devm_kfree(dev, transaction);
                        return -EINVAL;
+               }
 
                memcpy(transaction->params, skb->data +
                       transaction->aid_len + 4, transaction->params_len);