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>
This commit is contained in:
David Gibson 2021-12-29 15:08:28 +11:00
parent ca72944343
commit ff5afb96d0
3 changed files with 30 additions and 6 deletions

View file

@ -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;
}
}
}

View file

@ -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>;
};
};

View file

@ -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