]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: nfc: nci: Fix zero-length proprietary notifications
authorIan Ray <ian.ray@gehealthcare.com>
Mon, 2 Mar 2026 16:32:37 +0000 (18:32 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 5 Mar 2026 01:48:12 +0000 (17:48 -0800)
NCI NFC controllers may have proprietary OIDs with zero-length payload.
One example is: drivers/nfc/nxp-nci/core.c, NXP_NCI_RF_TXLDO_ERROR_NTF.

Allow a zero length payload in proprietary notifications *only*.

Before:

-- >8 --
kernel: nci: nci_recv_frame: len 3
-- >8 --

After:

-- >8 --
kernel: nci: nci_recv_frame: len 3
kernel: nci: nci_ntf_packet: NCI RX: MT=ntf, PBF=0, GID=0x1, OID=0x23, plen=0
kernel: nci: nci_ntf_packet: unknown ntf opcode 0x123
kernel: nfc nfc0: NFC: RF transmitter couldn't start. Bad power and/or configuration?
-- >8 --

After fixing the hardware:

-- >8 --
kernel: nci: nci_recv_frame: len 27
kernel: nci: nci_ntf_packet: NCI RX: MT=ntf, PBF=0, GID=0x1, OID=0x5, plen=24
kernel: nci: nci_rf_intf_activated_ntf_packet: rf_discovery_id 1
-- >8 --

Fixes: d24b03535e5e ("nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet")
Signed-off-by: Ian Ray <ian.ray@gehealthcare.com>
Link: https://patch.msgid.link/20260302163238.140576-1-ian.ray@gehealthcare.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/nfc/nci/core.c

index 6e9b76e2cc56dd7eb961f79879fe7fd3910c85f4..e95eef85971fa2dc9b97b9a6c1808bc8222fe5fd 100644 (file)
@@ -1482,10 +1482,20 @@ static bool nci_valid_size(struct sk_buff *skb)
        unsigned int hdr_size = NCI_CTRL_HDR_SIZE;
 
        if (skb->len < hdr_size ||
-           !nci_plen(skb->data) ||
            skb->len < hdr_size + nci_plen(skb->data)) {
                return false;
        }
+
+       if (!nci_plen(skb->data)) {
+               /* Allow zero length in proprietary notifications (0x20 - 0x3F). */
+               if (nci_opcode_oid(nci_opcode(skb->data)) >= 0x20 &&
+                   nci_mt(skb->data) == NCI_MT_NTF_PKT)
+                       return true;
+
+               /* Disallow zero length otherwise. */
+               return false;
+       }
+
        return true;
 }