2018-04-18 10:05:12

by Amit Pundir

[permalink] [raw]
Subject: [RESEND][PATCH 0/4] Few NFC fixes from android-4.14 tree

Hi,

Resending few NFC fixes I picked up from android-4.14 tree[1]
for review and comments. They seem reasonable upstream candidates.
My last attempt was not timed properly and it got lost between
Christmas-New Year break and then Meltdown-Spectre happened.

Also like to point out that I have not feature tested these patches
at all. Only made small cosmetic changes to the original patches
(removed Android-only tag and internal bug ID) and build tested for
arm/arm64 defconfigs, before posting them here for review.

Really appreciate any comments or feedback on how to take it forward.

Regards,
Amit Pundir
[1] https://android.googlesource.com/kernel/common/+log/android-4.14

Suren Baghdasaryan (4):
NFC: st21nfca: Fix out of bounds kernel access when handling ATR_REQ
NFC: st21nfca: Fix memory OOB and leak issues in connectivity events
handler
NFC: Fix possible memory corruption when handling SHDLC I-Frame
commands
NFC: fdp: Fix possible buffer overflow in WCS4000 NFC driver

drivers/nfc/fdp/i2c.c | 10 ++++++++++
drivers/nfc/st21nfca/dep.c | 3 ++-
drivers/nfc/st21nfca/se.c | 18 ++++++++++++++----
net/nfc/hci/core.c | 10 ++++++++++
4 files changed, 36 insertions(+), 5 deletions(-)

--
2.7.4


2018-04-18 10:05:19

by Amit Pundir

[permalink] [raw]
Subject: [RESEND][PATCH 2/4] NFC: st21nfca: Fix memory OOB and leak issues in connectivity events handler

From: Suren Baghdasaryan <[email protected]>

Overflow on memcpy is possible in kernel driver for st21nfca's
NFC HCI layer when handling connectivity events if aid_len or
params_len are bigger than the buffer size.
Memory leak is possible when parameter tag is invalid.

Signed-off-by: Suren Baghdasaryan <[email protected]>
Signed-off-by: Amit Pundir <[email protected]>
---
drivers/nfc/st21nfca/se.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)

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);

--
2.7.4

2018-04-23 17:22:17

by Amit Pundir

[permalink] [raw]
Subject: Re: [RESEND][PATCH 2/4] NFC: st21nfca: Fix memory OOB and leak issues in connectivity events handler

On 20 April 2018 at 22:15, Mark Greer <[email protected]> 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
> --

2018-04-23 09:16:38

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [RESEND][PATCH 4/4] NFC: fdp: Fix possible buffer overflow in WCS4000 NFC driver

On Wed, Apr 18, 2018 at 03:35:04PM +0530, Amit Pundir wrote:
> From: Suren Baghdasaryan <[email protected]>
>
> Possible buffer overflow when reading next_read_size bytes into
> tmp buffer after next_read_size was extracted from a previous packet.
>
> Signed-off-by: Suren Baghdasaryan <[email protected]>
> Signed-off-by: Amit Pundir <[email protected]>
> ---
> drivers/nfc/fdp/i2c.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c
> index c4da50e07bbc..08a4f82a2965 100644
> --- a/drivers/nfc/fdp/i2c.c
> +++ b/drivers/nfc/fdp/i2c.c
> @@ -176,6 +176,16 @@ static int fdp_nci_i2c_read(struct fdp_i2c_phy *phy, struct sk_buff **skb)
> /* Packet that contains a length */
> if (tmp[0] == 0 && tmp[1] == 0) {
> phy->next_read_size = (tmp[2] << 8) + tmp[3] + 3;
> + /*
> + * Ensure next_read_size does not exceed sizeof(tmp)
> + * for reading that many bytes during next iteration
> + */
> + if (phy->next_read_size > FDP_NCI_I2C_MAX_PAYLOAD) {
> + dev_dbg(&client->dev, "%s: corrupted packet\n",
> + __func__);

As Andy points out, no need for __func__ in any dev_dbg() call.

thanks,

greg k-h

2018-04-20 12:39:50

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [RESEND][PATCH 2/4] NFC: st21nfca: Fix memory OOB and leak issues in connectivity events handler

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;
> + }

--
Andy Shevchenko <[email protected]>
Intel Finland Oy

2018-04-23 17:21:01

by Amit Pundir

[permalink] [raw]
Subject: Re: [RESEND][PATCH 2/4] NFC: st21nfca: Fix memory OOB and leak issues in connectivity events handler

On 20 April 2018 at 18:09, Andy Shevchenko
<[email protected]> 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 <[email protected]>
> Intel Finland Oy

2018-04-18 10:05:23

by Amit Pundir

[permalink] [raw]
Subject: [RESEND][PATCH 3/4] NFC: Fix possible memory corruption when handling SHDLC I-Frame commands

From: Suren Baghdasaryan <[email protected]>

When handling SHDLC I-Frame commands "pipe" field used for indexing
into an array should be checked before usage. If left unchecked it
might access memory outside of the array of size NFC_HCI_MAX_PIPES(127).

Signed-off-by: Suren Baghdasaryan <[email protected]>
Signed-off-by: Amit Pundir <[email protected]>
---
net/nfc/hci/core.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index ac8030c4bcf8..19cb2e473ea6 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -209,6 +209,11 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
}
create_info = (struct hci_create_pipe_resp *)skb->data;

+ if (create_info->pipe >= NFC_HCI_MAX_PIPES) {
+ status = NFC_HCI_ANY_E_NOK;
+ goto exit;
+ }
+
/* Save the new created pipe and bind with local gate,
* the description for skb->data[3] is destination gate id
* but since we received this cmd from host controller, we
@@ -232,6 +237,11 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
}
delete_info = (struct hci_delete_pipe_noti *)skb->data;

+ if (delete_info->pipe >= NFC_HCI_MAX_PIPES) {
+ status = NFC_HCI_ANY_E_NOK;
+ goto exit;
+ }
+
hdev->pipes[delete_info->pipe].gate = NFC_HCI_INVALID_GATE;
hdev->pipes[delete_info->pipe].dest_host = NFC_HCI_INVALID_HOST;
break;
--
2.7.4

2018-04-20 12:41:34

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [RESEND][PATCH 4/4] NFC: fdp: Fix possible buffer overflow in WCS4000 NFC driver

On Wed, 2018-04-18 at 15:35 +0530, Amit Pundir wrote:

> + if (phy->next_read_size >
> FDP_NCI_I2C_MAX_PAYLOAD) {

> + dev_dbg(&client->dev, "%s: corrupted
> packet\n",
> + __func__);

If Android people would follow the kernel in reasonable time they may
have noticed Dynamic Debug functionality and how it works.

In this case the __func__ is superfluous.

> + phy->next_read_size = 5;
> + goto flush;
> + }
> } else {
> phy->next_read_size =
> FDP_NCI_I2C_MIN_PAYLOAD;
>

--
Andy Shevchenko <[email protected]>
Intel Finland Oy

2018-04-18 10:05:15

by Amit Pundir

[permalink] [raw]
Subject: [RESEND][PATCH 1/4] NFC: st21nfca: Fix out of bounds kernel access when handling ATR_REQ

From: Suren Baghdasaryan <[email protected]>

Out of bounds kernel accesses in st21nfca's NFC HCI layer
might happen when handling ATR_REQ events if user-specified
atr_req->length is bigger than the buffer size. In
that case memcpy() inside st21nfca_tm_send_atr_res() will
read extra bytes resulting in OOB read from the kernel heap.

Signed-off-by: Suren Baghdasaryan <[email protected]>
Signed-off-by: Amit Pundir <[email protected]>
---
drivers/nfc/st21nfca/dep.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/nfc/st21nfca/dep.c b/drivers/nfc/st21nfca/dep.c
index fd08be2917e6..3420c5104c94 100644
--- a/drivers/nfc/st21nfca/dep.c
+++ b/drivers/nfc/st21nfca/dep.c
@@ -217,7 +217,8 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,

atr_req = (struct st21nfca_atr_req *)skb->data;

- if (atr_req->length < sizeof(struct st21nfca_atr_req)) {
+ if (atr_req->length < sizeof(struct st21nfca_atr_req) ||
+ atr_req->length > skb->len) {
r = -EPROTO;
goto exit;
}
--
2.7.4

2018-04-20 16:45:10

by Mark Greer

[permalink] [raw]
Subject: Re: [RESEND][PATCH 2/4] NFC: st21nfca: Fix memory OOB and leak issues in connectivity events handler

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
--

2018-04-18 10:05:28

by Amit Pundir

[permalink] [raw]
Subject: [RESEND][PATCH 4/4] NFC: fdp: Fix possible buffer overflow in WCS4000 NFC driver

From: Suren Baghdasaryan <[email protected]>

Possible buffer overflow when reading next_read_size bytes into
tmp buffer after next_read_size was extracted from a previous packet.

Signed-off-by: Suren Baghdasaryan <[email protected]>
Signed-off-by: Amit Pundir <[email protected]>
---
drivers/nfc/fdp/i2c.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c
index c4da50e07bbc..08a4f82a2965 100644
--- a/drivers/nfc/fdp/i2c.c
+++ b/drivers/nfc/fdp/i2c.c
@@ -176,6 +176,16 @@ static int fdp_nci_i2c_read(struct fdp_i2c_phy *phy, struct sk_buff **skb)
/* Packet that contains a length */
if (tmp[0] == 0 && tmp[1] == 0) {
phy->next_read_size = (tmp[2] << 8) + tmp[3] + 3;
+ /*
+ * Ensure next_read_size does not exceed sizeof(tmp)
+ * for reading that many bytes during next iteration
+ */
+ if (phy->next_read_size > FDP_NCI_I2C_MAX_PAYLOAD) {
+ dev_dbg(&client->dev, "%s: corrupted packet\n",
+ __func__);
+ phy->next_read_size = 5;
+ goto flush;
+ }
} else {
phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD;

--
2.7.4

2018-04-23 10:02:50

by Amit Pundir

[permalink] [raw]
Subject: Re: [RESEND][PATCH 4/4] NFC: fdp: Fix possible buffer overflow in WCS4000 NFC driver

On 23 April 2018 at 14:46, Greg KH <[email protected]> wrote:
> On Wed, Apr 18, 2018 at 03:35:04PM +0530, Amit Pundir wrote:
>> From: Suren Baghdasaryan <[email protected]>
>>
>> Possible buffer overflow when reading next_read_size bytes into
>> tmp buffer after next_read_size was extracted from a previous packet.
>>
>> Signed-off-by: Suren Baghdasaryan <[email protected]>
>> Signed-off-by: Amit Pundir <[email protected]>
>> ---
>> drivers/nfc/fdp/i2c.c | 10 ++++++++++
>> 1 file changed, 10 insertions(+)
>>
>> diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c
>> index c4da50e07bbc..08a4f82a2965 100644
>> --- a/drivers/nfc/fdp/i2c.c
>> +++ b/drivers/nfc/fdp/i2c.c
>> @@ -176,6 +176,16 @@ static int fdp_nci_i2c_read(struct fdp_i2c_phy *phy, struct sk_buff **skb)
>> /* Packet that contains a length */
>> if (tmp[0] == 0 && tmp[1] == 0) {
>> phy->next_read_size = (tmp[2] << 8) + tmp[3] + 3;
>> + /*
>> + * Ensure next_read_size does not exceed sizeof(tmp)
>> + * for reading that many bytes during next iteration
>> + */
>> + if (phy->next_read_size > FDP_NCI_I2C_MAX_PAYLOAD) {
>> + dev_dbg(&client->dev, "%s: corrupted packet\n",
>> + __func__);
>
> As Andy points out, no need for __func__ in any dev_dbg() call.

Hi, Yes i'm working on v2 of this patch and on the comments I got on
another patch in this series.

Thanks,
Amit Pundir

>
> thanks,
>
> greg k-h