mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH] tlv: check incoming TLV headers for size
Date: Thu,  5 Mar 2026 08:44:48 +0100	[thread overview]
Message-ID: <20260305074448.3426540-1-s.hauer@pengutronix.de> (raw)

tlv_register_device() gets untrusted data in the incoming TLV header.
Add a size argument and check if the TLV is within the size boundaries
before processing it.
While at it check that the reserved field in the TLV header is set to
zero which is necessary should we later want to use it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/tlv/bus.c      | 20 +++++++++++++++++++-
 common/tlv/parser.c   |  2 +-
 common/tlv/register.c |  2 +-
 include/tlv/tlv.h     |  3 ++-
 test/self/tlv.c       |  4 ++--
 5 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/common/tlv/bus.c b/common/tlv/bus.c
index 29b6ce87bf..9c06baf360 100644
--- a/common/tlv/bus.c
+++ b/common/tlv/bus.c
@@ -14,9 +14,23 @@ static void tlv_devinfo(struct device *dev)
 	printf("Magic: %08x\n", tlvdev->magic);
 }
 
+static int tlv_header_check(struct tlv_header *header, size_t size)
+{
+	if (size < sizeof(*header))
+		return -ENODATA;
+
+	if (header->reserved != 0)
+		return -EINVAL;
+
+	if (size < tlv_total_len(header))
+		return -ENODATA;
+
+	return 0;
+}
+
 static struct device_node *tlv_parent_node;
 
-struct tlv_device *tlv_register_device(struct tlv_header *header,
+struct tlv_device *tlv_register_device(struct tlv_header *header, size_t size,
 				       struct device *parent)
 {
 	struct tlv_device *tlvdev;
@@ -25,6 +39,10 @@ struct tlv_device *tlv_register_device(struct tlv_header *header,
 	static int id = 0;
 	int ret;
 
+	ret = tlv_header_check(header, size);
+	if (ret)
+		return ERR_PTR(ret);
+
 	tlvdev = xzalloc(sizeof(*tlvdev));
 
 	dev = &tlvdev->dev;
diff --git a/common/tlv/parser.c b/common/tlv/parser.c
index 010e4cce38..4c0b6b5c6f 100644
--- a/common/tlv/parser.c
+++ b/common/tlv/parser.c
@@ -165,7 +165,7 @@ struct tlv_device *tlv_register_device_by_path(const char *path, struct device *
 	if (IS_ERR(header))
 		return ERR_CAST(header);
 
-	tlvdev = tlv_register_device(header, parent);
+	tlvdev = tlv_register_device(header, size, parent);
 	if (IS_ERR(tlvdev))
 		free(header);
 
diff --git a/common/tlv/register.c b/common/tlv/register.c
index a6d95fb8e0..66dd38f5d4 100644
--- a/common/tlv/register.c
+++ b/common/tlv/register.c
@@ -56,7 +56,7 @@ static int tlv_probe_from_compatible(struct device *dev)
 		goto err;
 	}
 
-	tlvdev = tlv_register_device(header, dev);
+	tlvdev = tlv_register_device(header, size, dev);
 	if (IS_ERR(tlvdev)) {
 		ret = PTR_ERR(tlvdev);
 		goto err;
diff --git a/include/tlv/tlv.h b/include/tlv/tlv.h
index 8b4ee1b399..c2812398dc 100644
--- a/include/tlv/tlv.h
+++ b/include/tlv/tlv.h
@@ -61,7 +61,8 @@ static inline struct device_node *tlv_of_node(struct tlv_device *tlvdev)
 	return tlvdev->dev.device_node;
 }
 
-struct tlv_device *tlv_register_device(struct tlv_header *header, struct device *parent);
+struct tlv_device *tlv_register_device(struct tlv_header *header, size_t size,
+				       struct device *parent);
 static inline struct tlv_header *tlv_device_header(struct tlv_device *tlvdev)
 {
 	return tlvdev->dev.platform_data;
diff --git a/test/self/tlv.c b/test/self/tlv.c
index 8f1b810b5a..cefa8b4a7a 100644
--- a/test/self/tlv.c
+++ b/test/self/tlv.c
@@ -60,14 +60,14 @@ static void test_lxa_tlv(void)
 		return;
 	}
 
-	cpu_tlvdev = tlv_register_device(cpu_blob, NULL);
+	cpu_tlvdev = tlv_register_device(cpu_blob, cpu_bloblen, NULL);
 	if (IS_ERR(cpu_tlvdev)) {
 		free(cpu_blob);
 		failed_tests++;
 		skipped_tests++;
 	}
 
-	io_tlvdev = tlv_register_device(io_blob, NULL);
+	io_tlvdev = tlv_register_device(io_blob, io_bloblen, NULL);
 	if (IS_ERR(io_tlvdev)) {
 		free(io_blob);
 		failed_tests++;
-- 
2.47.3




                 reply	other threads:[~2026-03-05  7:45 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260305074448.3426540-1-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox