From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29F8D2609C5 for ; Sun, 28 Jun 2026 21:00:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.51 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782680437; cv=none; b=SYRgH0/nLItjcbt5ahf8MSf+4KplmME2NAGuNDzapXBN90cnkCJrc4j2cHw2Z4b/fNyub4YsA9swnqYnuajweOmKfXn35YIByvapBPMRoX/Cb4zIwJONBiWdbmAT0rrIlzo0vRJCzmR0zJJ5Z0cadbrSBLMhpLJz5NmO2xsqN6A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782680437; c=relaxed/simple; bh=qsF2zEMe9MrdDEhAgXCZ9mk3Y52f0O8tyH/reTQnQAY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=sZnkA7p/hH5UQCfUHCbxJf1GYB8vNJtjDo2angYauOGrtQTM4FIznmIycDcaUSjreIn9lD4TJUy4cQ3Fb0WSFf6iMgeQeLrbWtsH+KkOwgq/DTMLi6vs4TpcJ/NT74u26FGxQxdU8Ab9LLfA8jlmPR0c2PEnLGD3v0M46Gs/Lgo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IeJxOIi4; arc=none smtp.client-ip=209.85.216.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IeJxOIi4" Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-37f816d01e3so1746884a91.2 for ; Sun, 28 Jun 2026 14:00:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782680435; x=1783285235; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=ntRF8aySUXd8W8x0gTrlgVfKPreN/+S0UpqzJ9bROBk=; b=IeJxOIi4S4HW7YnohOM0SPZK4r97SkQNLRMicJXbYe4wG+yMeuvTUifQhuapwmlIU8 z8GuEttFafgc1M9fi01xGBLSKPv43JlHYUYYzwLAfjLPf5rgFdvPe7ZV7Y2sYT7AVeX0 bqRxjGJiy5m5MVmP/572Lt963mwWw8N48rRWH5O72Ar7erf06R/ldIMchVpaUyPPuye9 h27LByN48BTW+PGLtl9kzDPIqIFA+AAEfhi22Wndzl1y5nTvgdR1AeaUyniSSW9zbsQk anksrX99V8kAQeNrlSi0a6DILZgdxREDH+BFlKarTYqHhPR+ytKPuv4or6YWqk+p/RGm jHfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782680435; x=1783285235; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ntRF8aySUXd8W8x0gTrlgVfKPreN/+S0UpqzJ9bROBk=; b=rYyHBlJ9SZ/E6zJG4AFN0RM2Wn5NXvJD/xU7W/opDkMq10iqivVNp4fnjQHjRekESq SAzYdIZL0EJp95B2ign+w03mFpcHSRNeahGUVBSV1qpqvUnH0MpeELEjWOkXHwJ9Ew2k XTfA0DsDSFz/aAprTSiJ4CltmEJOAkP+1gKCONo6Ds+4mgDBRZe1tCoAg5xPVn+jS+ou K030zpTen2iPsSl2fSB6wrByNoYav2jH7bjbE/KGDjZIVbphPKLumRs1xQs0uLbDCd0y mFL1Rk68ZMEZLXylSa6DahciwQ9HUPwhHjiIrJ3EaJldwU1MZu0PXfd3TysBGuCp6pyO 8UbA== X-Forwarded-Encrypted: i=1; AHgh+RpA1PNyNZVPz37yBosBUh4weXBlwrFQkMszdWQ9sPISOCGKimjf6pJgMWFv/e8TEvpjtcWhBiEcLdGryKI=@vger.kernel.org X-Gm-Message-State: AOJu0YwLbH+MM4L7nz/NwPFh6VK4Ibnm2lIDQhbACX7ICBGxMH2FT3XC xDeLoVA2cc7QKdxmKmdQ7ifmahw6VnYdJTDIB2zFbMAO57B/4u03c+Pu X-Gm-Gg: AfdE7cmx7WwzfvAaPCFEvF6PUyt+tweSPTeHe48qIWjyE0VUNq3VuZQ2rEqHyPIK/gF wUGcCrVb90vWSfuVU0DteHUAdLi48rxN+54JZutWkh+TaqCxOgufC/rlcRObZ2xyNX3D2nnKzjJ TKc6cbYUhTSNBk5OGxsDcf17FREyRFv1i8tVBSHmjDauk1c4c00rOUCCQ3N1AbbuDump5Zi/UDJ joq/G5urqmMC/QCWYP+O47dFETiPM/guCVF2BCYrKHUEmo94R+Vi+nMw93fMgWsPqrJ3S8aIcDq soi9gUUdytdIcimDcEe1RPFsi4rcYujxNQuZAVD5xYv+0j6CfJqpAbLD8dEdj1h7RFqcrRsfQlA EDp26Sb/hOeu5VOiqfbq/K9vkeqRl8VhTw5Q0dmOVR5gKggHGcFbQfq/FocIUJmHcMlXYyBMrhS 2SqgKeuADvPJlFVbFW4JBxnkVf2IG+CSKRAKIFYBE3p8Q4C/C9C2r0LeKOTUHvPVNdSc3FbIo= X-Received: by 2002:a17:90b:498c:b0:37f:b966:5f1b with SMTP id 98e67ed59e1d1-37fb9665fdamr5959083a91.4.1782680435345; Sun, 28 Jun 2026 14:00:35 -0700 (PDT) Received: from node ([149.40.62.34]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-37fd2bd0e49sm2390690a91.0.2026.06.28.14.00.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jun 2026 14:00:34 -0700 (PDT) From: Muhammad Bilal To: David Heidelberg , netdev@vger.kernel.org Cc: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , oe-linux-nfc@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH net] nfc: nci: fix out-of-bounds read in activation parameter parsing Date: Mon, 29 Jun 2026 02:00:26 +0500 Message-ID: <20260628210026.129941-1-meatuni001@gmail.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit nci_extract_activation_params_iso_dep() and nci_extract_activation_params_nfc_dep() receive a pointer into the RF_INTF_ACTIVATED_NTF notification but are not told how many bytes remain. Each reads a one-byte length field (rats_res_len, attrib_res_len, atr_res_len or atr_req_len) and then memcpy()s that many bytes from the packet. The length is clamped to the destination size, but it is never checked against the remaining activation-parameter data, so a notification whose length field is larger than the data present reads past the end of the buffer. The sibling nci_extract_rf_params_*() helpers were recently given a data_len argument and matching remaining-length checks, but the activation-parameter helpers were not updated. Pass the remaining length down and validate each field against it before copying, as the rf_params helpers do. Fixes: ac2068384034 ("NFC: Parse NCI NFC-DEP activation params") Cc: stable@vger.kernel.org Signed-off-by: Muhammad Bilal --- net/nfc/nci/ntf.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index c96512bb86531..63aa0a78472b1 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c @@ -525,7 +525,7 @@ static int nci_rf_discover_ntf_packet(struct nci_dev *ndev, static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, struct nci_rf_intf_activated_ntf *ntf, - const __u8 *data) + const __u8 *data, ssize_t data_len) { struct activation_params_nfca_poll_iso_dep *nfca_poll; struct activation_params_nfcb_poll_iso_dep *nfcb_poll; @@ -533,9 +533,14 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, switch (ntf->activation_rf_tech_and_mode) { case NCI_NFC_A_PASSIVE_POLL_MODE: nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; + if (data_len < 1) + return NCI_STATUS_RF_PROTOCOL_ERROR; nfca_poll->rats_res_len = min_t(__u8, *data++, NFC_ATS_MAXSIZE); + data_len--; pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); if (nfca_poll->rats_res_len > 0) { + if (data_len < nfca_poll->rats_res_len) + return NCI_STATUS_RF_PROTOCOL_ERROR; memcpy(nfca_poll->rats_res, data, nfca_poll->rats_res_len); } @@ -543,9 +548,14 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, case NCI_NFC_B_PASSIVE_POLL_MODE: nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; + if (data_len < 1) + return NCI_STATUS_RF_PROTOCOL_ERROR; nfcb_poll->attrib_res_len = min_t(__u8, *data++, 50); + data_len--; pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); if (nfcb_poll->attrib_res_len > 0) { + if (data_len < nfcb_poll->attrib_res_len) + return NCI_STATUS_RF_PROTOCOL_ERROR; memcpy(nfcb_poll->attrib_res, data, nfcb_poll->attrib_res_len); } @@ -562,7 +572,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, static int nci_extract_activation_params_nfc_dep(struct nci_dev *ndev, struct nci_rf_intf_activated_ntf *ntf, - const __u8 *data) + const __u8 *data, ssize_t data_len) { struct activation_params_poll_nfc_dep *poll; struct activation_params_listen_nfc_dep *listen; @@ -571,21 +581,33 @@ static int nci_extract_activation_params_nfc_dep(struct nci_dev *ndev, case NCI_NFC_A_PASSIVE_POLL_MODE: case NCI_NFC_F_PASSIVE_POLL_MODE: poll = &ntf->activation_params.poll_nfc_dep; + if (data_len < 1) + return NCI_STATUS_RF_PROTOCOL_ERROR; poll->atr_res_len = min_t(__u8, *data++, NFC_ATR_RES_MAXSIZE - 2); + data_len--; pr_debug("atr_res_len %d\n", poll->atr_res_len); - if (poll->atr_res_len > 0) + if (poll->atr_res_len > 0) { + if (data_len < poll->atr_res_len) + return NCI_STATUS_RF_PROTOCOL_ERROR; memcpy(poll->atr_res, data, poll->atr_res_len); + } break; case NCI_NFC_A_PASSIVE_LISTEN_MODE: case NCI_NFC_F_PASSIVE_LISTEN_MODE: listen = &ntf->activation_params.listen_nfc_dep; + if (data_len < 1) + return NCI_STATUS_RF_PROTOCOL_ERROR; listen->atr_req_len = min_t(__u8, *data++, NFC_ATR_REQ_MAXSIZE - 2); + data_len--; pr_debug("atr_req_len %d\n", listen->atr_req_len); - if (listen->atr_req_len > 0) + if (listen->atr_req_len > 0) { + if (data_len < listen->atr_req_len) + return NCI_STATUS_RF_PROTOCOL_ERROR; memcpy(listen->atr_req, data, listen->atr_req_len); + } break; default: @@ -806,12 +828,14 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, switch (ntf.rf_interface) { case NCI_RF_INTERFACE_ISO_DEP: err = nci_extract_activation_params_iso_dep(ndev, - &ntf, data); + &ntf, data, + ntf.activation_params_len); break; case NCI_RF_INTERFACE_NFC_DEP: err = nci_extract_activation_params_nfc_dep(ndev, - &ntf, data); + &ntf, data, + ntf.activation_params_len); break; case NCI_RF_INTERFACE_FRAME: -- 2.54.0