Message ID | 1524045904-7005-3-git-send-email-amit.pundir@linaro.org (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Samuel Ortiz |
Headers | show |
On Wed, 2018-04-18 at 15:35 +0530, Amit Pundir wrote: > if (skb->data[transaction->aid_len + 2] != > - NFC_EVT_TRANSACTION_PARAMS_TAG) > + NFC_EVT_TRANSACTION_PARAMS_TAG || > + skb->len < transaction->aid_len + transaction- > >params_len + 4) { > + devm_kfree(dev, transaction); Oh, no. This is not memory leak per se, this is bad choice of devm_ API where it should use plain kmalloc() / kfree(). > return -EPROTO; > + }
On Fri, Apr 20, 2018 at 03:39:46PM +0300, Andy Shevchenko wrote: > On Wed, 2018-04-18 at 15:35 +0530, Amit Pundir wrote: > > > if (skb->data[transaction->aid_len + 2] != > > - NFC_EVT_TRANSACTION_PARAMS_TAG) > > + NFC_EVT_TRANSACTION_PARAMS_TAG || > > + skb->len < transaction->aid_len + transaction- > > >params_len + 4) { > > > + devm_kfree(dev, transaction); > > Oh, no. > > This is not memory leak per se, this is bad choice of devm_ API where it > should use plain kmalloc() / kfree(). Also, there is no check to see if the allocation worked at all. Mark --
On 20 April 2018 at 18:09, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote: > On Wed, 2018-04-18 at 15:35 +0530, Amit Pundir wrote: > >> if (skb->data[transaction->aid_len + 2] != >> - NFC_EVT_TRANSACTION_PARAMS_TAG) >> + NFC_EVT_TRANSACTION_PARAMS_TAG || >> + skb->len < transaction->aid_len + transaction- >> >params_len + 4) { > >> + devm_kfree(dev, transaction); > > Oh, no. > > This is not memory leak per se, this is bad choice of devm_ API where it > should use plain kmalloc() / kfree(). > Hi, If I switch to kmalloc()/kfree() with allocation and may be pre-usage checks along the way up to nfc_genl_se_transaction() would that suffice? I believe, I still be needing the additional aid_len and params_len checks regardless, right? Regards, Amit Pundir >> return -EPROTO; >> + } > > -- > Andy Shevchenko <andriy.shevchenko@linux.intel.com> > Intel Finland Oy
On 20 April 2018 at 22:15, Mark Greer <mgreer@animalcreek.com> wrote: > On Fri, Apr 20, 2018 at 03:39:46PM +0300, Andy Shevchenko wrote: >> On Wed, 2018-04-18 at 15:35 +0530, Amit Pundir wrote: >> >> > if (skb->data[transaction->aid_len + 2] != >> > - NFC_EVT_TRANSACTION_PARAMS_TAG) >> > + NFC_EVT_TRANSACTION_PARAMS_TAG || >> > + skb->len < transaction->aid_len + transaction- >> > >params_len + 4) { >> >> > + devm_kfree(dev, transaction); >> >> Oh, no. >> >> This is not memory leak per se, this is bad choice of devm_ API where it >> should use plain kmalloc() / kfree(). > > Also, there is no check to see if the allocation worked at all. Ack. I'll add that in v2. Thanks. Regards, Amit Pundir > > Mark > --
diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index 4bed9e842db3..acdce231e227 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -322,23 +322,33 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, * AID 81 5 to 16 * PARAMETERS 82 0 to 255 */ - if (skb->len < NFC_MIN_AID_LENGTH + 2 && + if (skb->len < NFC_MIN_AID_LENGTH + 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) return -EPROTO; + /* + * Buffer should have enough space for at least + * two tag fields + two length fields + aid_len (skb->data[1]) + */ + if (skb->len < skb->data[1] + 4) + return -EPROTO; + transaction = (struct nfc_evt_transaction *)devm_kzalloc(dev, skb->len - 2, GFP_KERNEL); transaction->aid_len = skb->data[1]; memcpy(transaction->aid, &skb->data[2], transaction->aid_len); + transaction->params_len = skb->data[transaction->aid_len + 3]; - /* Check next byte is PARAMETERS tag (82) */ + /* Check next byte is PARAMETERS tag (82) and the length field */ if (skb->data[transaction->aid_len + 2] != - NFC_EVT_TRANSACTION_PARAMS_TAG) + NFC_EVT_TRANSACTION_PARAMS_TAG || + skb->len < transaction->aid_len + transaction->params_len + 4) { + devm_kfree(dev, transaction); return -EPROTO; + } - transaction->params_len = skb->data[transaction->aid_len + 3]; memcpy(transaction->params, skb->data + transaction->aid_len + 4, transaction->params_len);