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