libufdt: don't overflow when handling propeties > INT_MAX in size
Ensure property sizes (read as uint32_t) don't overflow the int return
value when being read. Fix up _ufdt_output_property_to_fdt() to avoid
int overflow if a property len is near INT_MAX in size.
Bug: 259062118
Ignore-AOSP-First: Security
Test: mmma system/libufdt
Test: system/libufdt/tests/run_tests.sh
Test: system/libufdt/tests/run_performance_test.sh
Change-Id: I03a56f68a7e53d941809560b943153b8fc31decc
Merged-In: I03a56f68a7e53d941809560b943153b8fc31decc
diff --git a/ufdt_convert.c b/ufdt_convert.c
index 9e7922a..8ce58b7 100644
--- a/ufdt_convert.c
+++ b/ufdt_convert.c
@@ -344,10 +344,11 @@
int data_len = 0;
void *data = ufdt_node_get_fdt_prop_data(&prop_node->parent, &data_len);
- int aligned_data_len = (data_len + (FDT_TAGSIZE - 1)) & ~(FDT_TAGSIZE - 1);
+ unsigned int aligned_data_len =
+ ((unsigned int)data_len + (FDT_TAGSIZE - 1u)) & ~(FDT_TAGSIZE - 1u);
- int new_propoff = fdt_size_dt_struct(fdtp);
- int new_prop_size = sizeof(struct fdt_property) + aligned_data_len;
+ unsigned int new_propoff = fdt_size_dt_struct(fdtp);
+ unsigned int new_prop_size = sizeof(struct fdt_property) + aligned_data_len;
struct fdt_property *new_prop =
(struct fdt_property *)((char *)fdtp + fdt_off_dt_struct(fdtp) +
new_propoff);
diff --git a/ufdt_node.c b/ufdt_node.c
index 309c674..730b401 100644
--- a/ufdt_node.c
+++ b/ufdt_node.c
@@ -118,7 +118,13 @@
}
const struct fdt_property *prop = (struct fdt_property *)node->fdt_tag_ptr;
if (out_len != NULL) {
- *out_len = fdt32_to_cpu(prop->len);
+ uint32_t prop_len = fdt32_to_cpu(prop->len);
+
+ if (prop_len > INT_MAX) {
+ return NULL;
+ }
+
+ *out_len = prop_len;
}
return (char *)prop->data;
}