* [PATCH] tlv: check incoming TLV headers for size
@ 2026-03-05 7:44 Sascha Hauer
0 siblings, 0 replies; only message in thread
From: Sascha Hauer @ 2026-03-05 7:44 UTC (permalink / raw)
To: Barebox List
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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-03-05 7:45 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-05 7:44 [PATCH] tlv: check incoming TLV headers for size Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox