Skip to content

Commit cb29867

Browse files
neosys007gregkh
authored andcommitted
nfc: microread: validate target discovery payload lengths
commit 2551946 upstream. microread_target_discovered() parses target discovery payloads from skb->data according to the HCI gate. The fixed field offsets and UID copies were checked only against the destination nfc_target buffers, not against the actual skb length. Validate that each gate-specific payload contains the fixed fields and UID bytes before reading or copying them. Fixes: cfad1ba ("NFC: Initial support for Inside Secure microread") Cc: stable@vger.kernel.org Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Link: https://patch.msgid.link/20260723103508.1-microread-v2-pengpeng@iscas.ac.cn Signed-off-by: David Heidelberg <david@ixit.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8d2c243 commit cb29867

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

drivers/nfc/microread/microread.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,46 +483,73 @@ static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate,
483483

484484
switch (gate) {
485485
case MICROREAD_GATE_ID_MREAD_ISO_A:
486+
if (skb->len <= MICROREAD_EMCF_A_LEN) {
487+
r = -EINVAL;
488+
goto exit_free;
489+
}
490+
486491
targets->supported_protocols =
487492
nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A_SAK]);
488493
targets->sens_res =
489494
be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A_ATQA]);
490495
targets->sel_res = skb->data[MICROREAD_EMCF_A_SAK];
491496
targets->nfcid1_len = skb->data[MICROREAD_EMCF_A_LEN];
492-
if (targets->nfcid1_len > sizeof(targets->nfcid1)) {
497+
if (targets->nfcid1_len > sizeof(targets->nfcid1) ||
498+
targets->nfcid1_len > skb->len - MICROREAD_EMCF_A_UID) {
493499
r = -EINVAL;
494500
goto exit_free;
495501
}
496502
memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A_UID],
497503
targets->nfcid1_len);
498504
break;
499505
case MICROREAD_GATE_ID_MREAD_ISO_A_3:
506+
if (skb->len <= MICROREAD_EMCF_A3_LEN) {
507+
r = -EINVAL;
508+
goto exit_free;
509+
}
510+
500511
targets->supported_protocols =
501512
nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A3_SAK]);
502513
targets->sens_res =
503514
be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A3_ATQA]);
504515
targets->sel_res = skb->data[MICROREAD_EMCF_A3_SAK];
505516
targets->nfcid1_len = skb->data[MICROREAD_EMCF_A3_LEN];
506-
if (targets->nfcid1_len > sizeof(targets->nfcid1)) {
517+
if (targets->nfcid1_len > sizeof(targets->nfcid1) ||
518+
targets->nfcid1_len > skb->len - MICROREAD_EMCF_A3_UID) {
507519
r = -EINVAL;
508520
goto exit_free;
509521
}
510522
memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A3_UID],
511523
targets->nfcid1_len);
512524
break;
513525
case MICROREAD_GATE_ID_MREAD_ISO_B:
526+
if (skb->len < MICROREAD_EMCF_B_UID + 4) {
527+
r = -EINVAL;
528+
goto exit_free;
529+
}
530+
514531
targets->supported_protocols = NFC_PROTO_ISO14443_B_MASK;
515532
memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_B_UID], 4);
516533
targets->nfcid1_len = 4;
517534
break;
518535
case MICROREAD_GATE_ID_MREAD_NFC_T1:
536+
if (skb->len < MICROREAD_EMCF_T1_UID + 4) {
537+
r = -EINVAL;
538+
goto exit_free;
539+
}
540+
519541
targets->supported_protocols = NFC_PROTO_JEWEL_MASK;
520542
targets->sens_res =
521543
le16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_T1_ATQA]);
522544
memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T1_UID], 4);
523545
targets->nfcid1_len = 4;
524546
break;
525547
case MICROREAD_GATE_ID_MREAD_NFC_T3:
548+
if (skb->len < MICROREAD_EMCF_T3_UID + 8) {
549+
r = -EINVAL;
550+
goto exit_free;
551+
}
552+
526553
targets->supported_protocols = NFC_PROTO_FELICA_MASK;
527554
memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T3_UID], 8);
528555
targets->nfcid1_len = 8;

0 commit comments

Comments
 (0)