public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] nfc: llcp: fix tlv offset wrap and missing bounds checks
@ 2026-03-24 21:25 Oleh Konko
  2026-03-26 20:01 ` Simon Horman
  0 siblings, 1 reply; 3+ messages in thread
From: Oleh Konko @ 2026-03-24 21:25 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org

nfc_llcp_parse_gb_tlv() and nfc_llcp_parse_connection_tlv() iterate a
u16 tlv_array_len with a u8 offset. once cumulative TLV consumption
crosses 255 bytes, offset wraps and the loop may continue past the
declared TLV array bounds.

both parsers also read tlv[1] before checking that a full 2-byte TLV
header remains, and they advance by length + 2 without validating that
the declared payload still fits in the remaining array.

fix this by widening offset to u16 and by rejecting incomplete headers
or truncated TLVs before dereferencing or advancing the cursor.

Fixes: d646960f7986 ("NFC: Initial LLCP support")
Cc: stable@vger.kernel.org
Reported-by: Oleh Konko <security@1seal.org>
Signed-off-by: Oleh Konko <security@1seal.org>
---
 net/nfc/llcp_commands.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index 291f26fac..157afd62f 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -193,7 +193,8 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
 			  const u8 *tlv_array, u16 tlv_array_len)
 {
 	const u8 *tlv = tlv_array;
-	u8 type, length, offset = 0;
+	u8 type, length;
+	u16 offset = 0;
 
 	pr_debug("TLV array length %d\n", tlv_array_len);
 
@@ -201,6 +202,9 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
 		return -ENODEV;
 
 	while (offset < tlv_array_len) {
+		if (tlv_array_len - offset < 2)
+			return -EINVAL;
+
 		type = tlv[0];
 		length = tlv[1];
 
@@ -227,6 +231,9 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
 			break;
 		}
 
+		if (tlv_array_len - offset < (u16)length + 2)
+			return -EINVAL;
+
 		offset += length + 2;
 		tlv += length + 2;
 	}
@@ -243,7 +250,8 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
 				  const u8 *tlv_array, u16 tlv_array_len)
 {
 	const u8 *tlv = tlv_array;
-	u8 type, length, offset = 0;
+	u8 type, length;
+	u16 offset = 0;
 
 	pr_debug("TLV array length %d\n", tlv_array_len);
 
@@ -251,6 +259,9 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
 		return -ENOTCONN;
 
 	while (offset < tlv_array_len) {
+		if (tlv_array_len - offset < 2)
+			return -EINVAL;
+
 		type = tlv[0];
 		length = tlv[1];
 
@@ -270,6 +281,9 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
 			break;
 		}
 
+		if (tlv_array_len - offset < (u16)length + 2)
+			return -EINVAL;
+
 		offset += length + 2;
 		tlv += length + 2;
 	}
-- 
2.50.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread
* [PATCH net] nfc: llcp: fix tlv offset wrap and missing bounds checks
@ 2026-03-24 19:54 Oleh Konko
  0 siblings, 0 replies; 3+ messages in thread
From: Oleh Konko @ 2026-03-24 19:54 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org

nfc_llcp_parse_gb_tlv() and nfc_llcp_parse_connection_tlv() iterate a
u16 tlv_array_len with a u8 offset. once cumulative TLV consumption
crosses 255 bytes, offset wraps and the loop may continue past the
declared TLV array bounds.

both parsers also read tlv[1] before checking that a full 2-byte TLV
header remains, and they advance by length + 2 without validating that
the declared payload still fits in the remaining array.

fix this by widening offset to u16 and by rejecting incomplete headers
or truncated TLVs before dereferencing or advancing the cursor.

Fixes: d646960f7986 ("NFC: Initial LLCP support")
Cc: stable@vger.kernel.org
Reported-by: Oleh Konko <security@1seal.org>
Signed-off-by: Oleh Konko <security@1seal.org>
---
 net/nfc/llcp_commands.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index 291f26fac..157afd62f 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -193,7 +193,8 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
 			  const u8 *tlv_array, u16 tlv_array_len)
 {
 	const u8 *tlv = tlv_array;
-	u8 type, length, offset = 0;
+	u8 type, length;
+	u16 offset = 0;
 
 	pr_debug("TLV array length %d\n", tlv_array_len);
 
@@ -201,6 +202,9 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
 		return -ENODEV;
 
 	while (offset < tlv_array_len) {
+		if (tlv_array_len - offset < 2)
+			return -EINVAL;
+
 		type = tlv[0];
 		length = tlv[1];
 
@@ -227,6 +231,9 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
 			break;
 		}
 
+		if (tlv_array_len - offset < (u16)length + 2)
+			return -EINVAL;
+
 		offset += length + 2;
 		tlv += length + 2;
 	}
@@ -243,7 +250,8 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
 				  const u8 *tlv_array, u16 tlv_array_len)
 {
 	const u8 *tlv = tlv_array;
-	u8 type, length, offset = 0;
+	u8 type, length;
+	u16 offset = 0;
 
 	pr_debug("TLV array length %d\n", tlv_array_len);
 
@@ -251,6 +259,9 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
 		return -ENOTCONN;
 
 	while (offset < tlv_array_len) {
+		if (tlv_array_len - offset < 2)
+			return -EINVAL;
+
 		type = tlv[0];
 		length = tlv[1];
 
@@ -270,6 +281,9 @@ int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
 			break;
 		}
 
+		if (tlv_array_len - offset < (u16)length + 2)
+			return -EINVAL;
+
 		offset += length + 2;
 		tlv += length + 2;
 	}
-- 
2.50.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-03-26 20:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-24 21:25 [PATCH net] nfc: llcp: fix tlv offset wrap and missing bounds checks Oleh Konko
2026-03-26 20:01 ` Simon Horman
  -- strict thread matches above, loose matches on Subject: below --
2026-03-24 19:54 Oleh Konko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox