From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 01/17] fdt: Check blob size during unflattening
Date: Wed, 23 Jun 2021 07:16:16 +0200 [thread overview]
Message-ID: <20210623051632.30253-2-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20210623051632.30253-1-s.hauer@pengutronix.de>
of_unflatten_dtb() doesn't check the size of the device tree blob
passed to it. Add a size argument end add checks for the size. Some
callers have no idea of the buffer size themselves, INT_MAX is passed
in these cases.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/qemu-virt/board.c | 4 ++--
arch/arm/boards/raspberry-pi/rpi-common.c | 2 +-
arch/arm/boards/webasto-ccbv2/board.c | 2 +-
arch/arm/lib32/bootm.c | 2 +-
commands/of_diff.c | 2 +-
commands/of_display_timings.c | 2 +-
commands/of_dump.c | 4 ++--
commands/of_overlay.c | 5 +++--
commands/oftree.c | 2 +-
common/blspec.c | 7 ++++---
common/bootm.c | 4 ++--
common/efi/efi.c | 2 +-
common/image-fit.c | 2 +-
common/state/backend_format_dtb.c | 2 +-
drivers/of/base.c | 2 +-
drivers/of/fdt.c | 17 ++++++++++++-----
include/of.h | 4 ++--
17 files changed, 37 insertions(+), 28 deletions(-)
diff --git a/arch/arm/boards/qemu-virt/board.c b/arch/arm/boards/qemu-virt/board.c
index 5ce1ecfc24..b2a3cb29ab 100644
--- a/arch/arm/boards/qemu-virt/board.c
+++ b/arch/arm/boards/qemu-virt/board.c
@@ -31,14 +31,14 @@ static int replace_dtb(void) {
return 0;
}
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, INT_MAX);
if (!of_device_is_compatible(root, "linux,dummy-virt")) {
of_delete_node(root);
return 0;
}
- overlay = of_unflatten_dtb(__dtb_overlay_of_flash_start);
+ overlay = of_unflatten_dtb(__dtb_overlay_of_flash_start, INT_MAX);
of_overlay_apply_tree(root, overlay);
return barebox_register_of(root);
diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c
index e326732b3a..6c5df6fd69 100644
--- a/arch/arm/boards/raspberry-pi/rpi-common.c
+++ b/arch/arm/boards/raspberry-pi/rpi-common.c
@@ -430,7 +430,7 @@ static int rpi_vc_fdt_bootargs(void *fdt)
struct device_node *root = NULL, *node;
const char *cmdline;
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, INT_MAX);
if (IS_ERR(root)) {
ret = PTR_ERR(root);
root = NULL;
diff --git a/arch/arm/boards/webasto-ccbv2/board.c b/arch/arm/boards/webasto-ccbv2/board.c
index a78258ea6a..477771309e 100644
--- a/arch/arm/boards/webasto-ccbv2/board.c
+++ b/arch/arm/boards/webasto-ccbv2/board.c
@@ -28,7 +28,7 @@ static int ccbv2_probe(struct device_d *dev)
return 0;
fdt = (void*)OPTEE_OVERLAY_LOCATION;
- overlay = of_unflatten_dtb(fdt);
+ overlay = of_unflatten_dtb(fdt, INT_MAX);
if (IS_ERR(overlay))
return PTR_ERR(overlay);
diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index 28a645a9d0..0ffb374cf1 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -421,7 +421,7 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data, void **outfdt)
if (IS_BUILTIN(CONFIG_OFTREE)) {
struct device_node *root;
- root = of_unflatten_dtb(oftree);
+ root = of_unflatten_dtb(oftree, header->totalsize);
if (IS_ERR(root)) {
pr_err("unable to unflatten devicetree\n");
goto err_free;
diff --git a/commands/of_diff.c b/commands/of_diff.c
index ec039776cf..e1ac98c26e 100644
--- a/commands/of_diff.c
+++ b/commands/of_diff.c
@@ -44,7 +44,7 @@ static struct device_node *get_tree(const char *filename, struct device_node *ro
if (ret)
return ERR_PTR(ret);
- node = of_unflatten_dtb(fdt);
+ node = of_unflatten_dtb(fdt, size);
free(fdt);
diff --git a/commands/of_display_timings.c b/commands/of_display_timings.c
index 27b91f311a..4e5ec223b7 100644
--- a/commands/of_display_timings.c
+++ b/commands/of_display_timings.c
@@ -83,7 +83,7 @@ static int do_of_display_timings(int argc, char *argv[])
return -EINVAL;
}
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, size);
free(fdt);
diff --git a/commands/of_dump.c b/commands/of_dump.c
index 2089c07ef7..5223ba63ad 100644
--- a/commands/of_dump.c
+++ b/commands/of_dump.c
@@ -71,7 +71,7 @@ static int do_of_dump(int argc, char *argv[])
return -errno;
}
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, size);
free(fdt);
@@ -88,7 +88,7 @@ static int do_of_dump(int argc, char *argv[])
/* create a copy of internal devicetree */
void *fdt;
fdt = of_flatten_dtb(root);
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, fdt_totalsize(fdt));
free(fdt);
diff --git a/commands/of_overlay.c b/commands/of_overlay.c
index aa4b6484ca..9a4c008efc 100644
--- a/commands/of_overlay.c
+++ b/commands/of_overlay.c
@@ -17,6 +17,7 @@ static int do_of_overlay(int argc, char *argv[])
struct fdt_header *fdt;
struct device_node *overlay;
const char *search_path = NULL;
+ size_t size;
while ((opt = getopt(argc, argv, "S:")) > 0) {
switch (opt) {
@@ -31,13 +32,13 @@ static int do_of_overlay(int argc, char *argv[])
if (argc != optind + 1)
return COMMAND_ERROR_USAGE;
- fdt = read_file(argv[optind], NULL);
+ fdt = read_file(argv[optind], &size);
if (!fdt) {
printf("cannot read %s\n", argv[optind]);
return 1;
}
- overlay = of_unflatten_dtb(fdt);
+ overlay = of_unflatten_dtb(fdt, size);
free(fdt);
if (IS_ERR(overlay))
return PTR_ERR(overlay);
diff --git a/commands/oftree.c b/commands/oftree.c
index 1d902f2830..7d4b08c9d3 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -82,7 +82,7 @@ static int do_oftree(int argc, char *argv[])
return 1;
}
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, size);
free(fdt);
diff --git a/common/blspec.c b/common/blspec.c
index ad80d7a8cd..056c0dbf7f 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -40,17 +40,18 @@ static int blspec_apply_oftree_overlay(char *file, const char *abspath,
struct device_node *overlay;
char *path;
char *firmware_path;
+ size_t size;
path = basprintf("%s/%s", abspath, file);
- fdt = read_file(path, NULL);
+ fdt = read_file(path, &size);
if (!fdt) {
pr_warn("unable to read \"%s\"\n", path);
ret = -EINVAL;
goto out;
}
- overlay = of_unflatten_dtb(fdt);
+ overlay = of_unflatten_dtb(fdt, size);
free(fdt);
if (IS_ERR(overlay)) {
ret = PTR_ERR(overlay);
@@ -490,7 +491,7 @@ static bool entry_is_of_compatible(struct blspec_entry *entry)
goto out;
}
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, size);
if (IS_ERR(root)) {
ret = false;
root = NULL;
diff --git a/common/bootm.c b/common/bootm.c
index 644443a021..89e3e93f2c 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -361,7 +361,7 @@ void *bootm_get_devicetree(struct image_data *data)
if (ret)
return ERR_PTR(ret);
- data->of_root_node = of_unflatten_dtb(of_tree);
+ data->of_root_node = of_unflatten_dtb(of_tree, of_size);
} else if (data->oftree_file) {
size_t size;
@@ -389,7 +389,7 @@ void *bootm_get_devicetree(struct image_data *data)
if (ret)
return ERR_PTR(ret);
- data->of_root_node = of_unflatten_dtb(oftree);
+ data->of_root_node = of_unflatten_dtb(oftree, size);
free(oftree);
diff --git a/common/efi/efi.c b/common/efi/efi.c
index 01003dc00f..7f12342cf9 100644
--- a/common/efi/efi.c
+++ b/common/efi/efi.c
@@ -437,7 +437,7 @@ static int efi_late_init(void)
return -EINVAL;
}
- root = of_unflatten_dtb(fdt);
+ root = of_unflatten_dtb(fdt, size);
free(fdt);
diff --git a/common/image-fit.c b/common/image-fit.c
index 2c5ef7f687..c1a34a4405 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -754,7 +754,7 @@ static int fit_do_open(struct fit_handle *handle)
const char *desc = "(no description)";
struct device_node *root;
- root = of_unflatten_dtb_const(handle->fit);
+ root = of_unflatten_dtb_const(handle->fit, handle->size);
if (IS_ERR(root))
return PTR_ERR(root);
diff --git a/common/state/backend_format_dtb.c b/common/state/backend_format_dtb.c
index 48f30db1f5..d0fc948859 100644
--- a/common/state/backend_format_dtb.c
+++ b/common/state/backend_format_dtb.c
@@ -59,7 +59,7 @@ static int state_backend_format_dtb_verify(struct state_backend_format *format,
fdtb->root = NULL;
}
- root = of_unflatten_dtb(buf);
+ root = of_unflatten_dtb(buf, dtb_len);
if (IS_ERR(root)) {
dev_err(fdtb->dev, "Failed to unflatten dtb from buffer with length %zd, %ld\n",
len, PTR_ERR(root));
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 193bae7fa0..b92e21ecf8 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1720,7 +1720,7 @@ int barebox_register_fdt(const void *dtb)
if (root_node)
return -EBUSY;
- root = of_unflatten_dtb(dtb);
+ root = of_unflatten_dtb(dtb, INT_MAX);
if (IS_ERR(root)) {
pr_err("Cannot unflatten dtb: %pe\n", root);
return PTR_ERR(root);
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index d98913e54a..f72f5e3a30 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -114,7 +114,8 @@ static int of_unflatten_reservemap(struct device_node *root,
* Parse a flat device tree binary blob and return a pointer to the
* unflattened tree.
*/
-static struct device_node *__of_unflatten_dtb(const void *infdt, bool constprops)
+static struct device_node *__of_unflatten_dtb(const void *infdt, int size,
+ bool constprops)
{
const void *nodep; /* property node pointer */
uint32_t tag; /* tag */
@@ -131,6 +132,9 @@ static struct device_node *__of_unflatten_dtb(const void *infdt, bool constprops
unsigned int maxlen;
const struct fdt_header *fdt = infdt;
+ if (size < sizeof(struct fdt_header))
+ return ERR_PTR(-EINVAL);
+
if (fdt->magic != cpu_to_fdt32(FDT_MAGIC)) {
pr_err("bad magic: 0x%08x\n", fdt32_to_cpu(fdt->magic));
return ERR_PTR(-EINVAL);
@@ -147,6 +151,9 @@ static struct device_node *__of_unflatten_dtb(const void *infdt, bool constprops
f.off_dt_strings = fdt32_to_cpu(fdt->off_dt_strings);
f.size_dt_strings = fdt32_to_cpu(fdt->size_dt_strings);
+ if (f.totalsize > size)
+ return ERR_PTR(-EINVAL);
+
if (f.off_dt_struct + f.size_dt_struct > f.totalsize) {
pr_err("unflatten: dt size exceeds total size\n");
return ERR_PTR(-ESPIPE);
@@ -274,9 +281,9 @@ err:
* Parse a flat device tree binary blob and return a pointer to the unflattened
* tree. The tree must be freed after use with of_delete_node().
*/
-struct device_node *of_unflatten_dtb(const void *infdt)
+struct device_node *of_unflatten_dtb(const void *infdt, int size)
{
- return __of_unflatten_dtb(infdt, false);
+ return __of_unflatten_dtb(infdt, size, false);
}
/**
@@ -290,9 +297,9 @@ struct device_node *of_unflatten_dtb(const void *infdt)
* whole lifetime of the returned tree. This is normally not what you want, so
* use of_unflatten_dtb() instead.
*/
-struct device_node *of_unflatten_dtb_const(const void *infdt)
+struct device_node *of_unflatten_dtb_const(const void *infdt, int size)
{
- return __of_unflatten_dtb(infdt, true);
+ return __of_unflatten_dtb(infdt, size, true);
}
struct fdt {
diff --git a/include/of.h b/include/of.h
index d67a40bd19..cdf01d5b4d 100644
--- a/include/of.h
+++ b/include/of.h
@@ -109,8 +109,8 @@ void of_print_properties(struct device_node *node);
void of_diff(struct device_node *a, struct device_node *b, int indent);
int of_probe(void);
int of_parse_dtb(struct fdt_header *fdt);
-struct device_node *of_unflatten_dtb(const void *fdt);
-struct device_node *of_unflatten_dtb_const(const void *infdt);
+struct device_node *of_unflatten_dtb(const void *fdt, int size);
+struct device_node *of_unflatten_dtb_const(const void *infdt, int size);
struct cdev;
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2021-06-23 5:18 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-23 5:16 [PATCH v2 00/17] Apply device tree overlays to kernel tree Sascha Hauer
2021-06-23 5:16 ` Sascha Hauer [this message]
2021-06-23 5:16 ` [PATCH 02/17] firmware: make device_node argument non const Sascha Hauer
2021-06-23 5:16 ` [PATCH 03/17] libbb: Add find_path function Sascha Hauer
2021-06-23 5:16 ` [PATCH 04/17] firmware: consolidate ifdefs Sascha Hauer
2021-06-23 5:16 ` [PATCH 05/17] firmware: Add search path Sascha Hauer
2021-06-23 5:16 ` [PATCH 06/17] firmware: Fix device_node matching Sascha Hauer
2021-06-23 5:16 ` [PATCH 07/17] firmware: recognize by reproducible name Sascha Hauer
2021-06-23 5:16 ` [PATCH 08/17] blspec: Set firmware searchpath Sascha Hauer
2021-06-23 5:16 ` [PATCH 09/17] overlay: only apply compatible trees Sascha Hauer
2021-06-23 5:16 ` [PATCH 10/17] overlay: Add of_overlay_apply_file() Sascha Hauer
2021-06-23 5:16 ` [PATCH 11/17] firmware: Load from global search path Sascha Hauer
2021-06-23 5:16 ` [PATCH 12/17] blspec: Rework firmware load Sascha Hauer
2021-06-23 5:16 ` [PATCH 13/17] of_overlay: apply overlays during booting Sascha Hauer
2021-06-23 5:16 ` [PATCH 14/17] blspec: Apply overlays from rootfs Sascha Hauer
2021-06-23 5:16 ` [PATCH 15/17] doc: devicetree: Refer to internal device tree also as live tree Sascha Hauer
2021-06-23 5:16 ` [PATCH 16/17] Documentation: Add documentation for device tree overlays Sascha Hauer
2021-06-23 6:13 ` Ahmad Fatoum
2021-06-23 19:37 ` Trent Piepho
2021-06-24 8:48 ` Sascha Hauer
2021-06-23 5:16 ` [PATCH 17/17] of_firmware: Fix handling of firmware-name property Sascha Hauer
-- strict thread matches above, loose matches on Subject: below --
2021-03-10 13:28 [PATCH 00/17] Apply device tree overlays to kernel tree Sascha Hauer
2021-03-10 13:28 ` [PATCH 01/17] fdt: Check blob size during unflattening Sascha Hauer
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=20210623051632.30253-2-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