aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2021-12-29 15:08:28 +1100
committerDavid Gibson <david@gibson.dropbear.id.au>2021-12-29 17:04:18 +1100
commitff5afb96d0c08133b6f709a197b8bda023531757 (patch)
treebec484328c30edc7132abba86a80d06bf250f0fc
parentca7294434309930076ff99ff4f0c817499f50f5a (diff)
downloaddtc-ff5afb96d0c08133b6f709a197b8bda023531757.zip
dtc-ff5afb96d0c08133b6f709a197b8bda023531757.tar.gz
dtc-ff5afb96d0c08133b6f709a197b8bda023531757.tar.bz2
Handle integer overflow in check_property_phandle_args()
If the corresponding '#xxx-cells' value is much too large, an integer overflow can prevent the checks in check_property_phandle_args() from correctly determining that the checked property is too short for the given cells value. This leads to an infinite loops. This patch fixes the bug, and adds a testcase for it. Further information in https://github.com/dgibson/dtc/issues/64 Reported-by: Anciety <anciety@pku.edu.cn> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--checks.c15
-rw-r--r--tests/phandle-args-overflow.dts18
-rwxr-xr-xtests/run_tests.sh3
3 files changed, 30 insertions, 6 deletions
diff --git a/checks.c b/checks.c
index 781ba11..9f31d26 100644
--- a/checks.c
+++ b/checks.c
@@ -1382,10 +1382,10 @@ struct provider {
};
static void check_property_phandle_args(struct check *c,
- struct dt_info *dti,
- struct node *node,
- struct property *prop,
- const struct provider *provider)
+ struct dt_info *dti,
+ struct node *node,
+ struct property *prop,
+ const struct provider *provider)
{
struct node *root = dti->dt;
unsigned int cell, cellsize = 0;
@@ -1401,6 +1401,7 @@ static void check_property_phandle_args(struct check *c,
struct node *provider_node;
struct property *cellprop;
cell_t phandle;
+ unsigned int expected;
phandle = propval_cell_n(prop, cell);
/*
@@ -1450,10 +1451,12 @@ static void check_property_phandle_args(struct check *c,
break;
}
- if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
+ expected = (cell + cellsize + 1) * sizeof(cell_t);
+ if ((expected <= cell) || prop->val.len < expected) {
FAIL_PROP(c, dti, node, prop,
- "property size (%d) too small for cell size %d",
+ "property size (%d) too small for cell size %u",
prop->val.len, cellsize);
+ break;
}
}
}
diff --git a/tests/phandle-args-overflow.dts b/tests/phandle-args-overflow.dts
new file mode 100644
index 0000000..8c8c5d7
--- /dev/null
+++ b/tests/phandle-args-overflow.dts
@@ -0,0 +1,18 @@
+/dts-v1/;
+
+/*
+ * https://github.com/dgibson/dtc/issues/64
+ *
+ * Certain dtc versions had a bug where this input caused an infinite
+ * loop in check_property_phandle_args().
+ *
+ */
+
+/ {
+ clocks = <&ref &ref>;
+
+ ref: poc {
+ phandle = <1>;
+ #clock-cells = <0xffffffff>;
+ };
+};
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 11068e1..5e4e7c4 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -513,6 +513,9 @@ libfdt_tests () {
run_dtc_test -I fs -O dtb -o fs.test_tree1.test.dtb $FSBASE/test_tree1
run_test dtbs_equal_unordered -m fs.test_tree1.test.dtb test_tree1.dtb
+ ## https://github.com/dgibson/dtc/issues/64
+ check_tests "$SRCDIR/phandle-args-overflow.dts" clocks_property
+
# check full tests
for good in test_tree1.dtb; do
run_test check_full $good