From: Ryosuke Yasuoka ryasuoka@redhat.com
mainline inclusion from mainline-v6.10-rc1 commit e4a87abf588536d1cdfb128595e6e680af5cf3ed category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9QG8F CVE: CVE-2024-35915
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
syzbot reported the following uninit-value access issue [1]
nci_rx_work() parses received packet from ndev->rx_q. It should be validated header size, payload size and total packet size before processing the packet. If an invalid packet is detected, it should be silently discarded.
Fixes: d24b03535e5e ("nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet") Reported-and-tested-by: syzbot+d7b4dc6cd50410152534@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=d7b4dc6cd50410152534 [1] Signed-off-by: Ryosuke Yasuoka ryasuoka@redhat.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: David S. Miller davem@davemloft.net
Conflicts: net/nfc/nci/core.c [Some contexts around nci_valid_size different. No functional impact.] Signed-off-by: Zheng Zucheng zhengzucheng@huawei.com --- net/nfc/nci/core.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 5f1ec7162cbb..7f38a1ecbba4 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -1448,6 +1448,20 @@ int nci_core_ntf_packet(struct nci_dev *ndev, __u16 opcode, ndev->ops->n_core_ops); }
+static bool nci_valid_size(struct sk_buff *skb) +{ + unsigned int hdr_size = NCI_CTRL_HDR_SIZE; + + BUILD_BUG_ON(NCI_CTRL_HDR_SIZE != NCI_DATA_HDR_SIZE); + + if (skb->len < hdr_size || + !nci_plen(skb->data) || + skb->len < hdr_size + nci_plen(skb->data)) { + return false; + } + return true; +} + /* ---- NCI TX Data worker thread ---- */
static void nci_tx_work(struct work_struct *work) @@ -1498,7 +1512,7 @@ static void nci_rx_work(struct work_struct *work) nfc_send_to_raw_sock(ndev->nfc_dev, skb, RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
- if (!nci_plen(skb->data)) { + if (!nci_valid_size(skb)) { kfree_skb(skb); kcov_remote_stop(); break;