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>main
parent
ca72944343
commit
ff5afb96d0
15
checks.c
15
checks.c
|
@ -1382,10 +1382,10 @@ struct provider {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void check_property_phandle_args(struct check *c,
|
static void check_property_phandle_args(struct check *c,
|
||||||
struct dt_info *dti,
|
struct dt_info *dti,
|
||||||
struct node *node,
|
struct node *node,
|
||||||
struct property *prop,
|
struct property *prop,
|
||||||
const struct provider *provider)
|
const struct provider *provider)
|
||||||
{
|
{
|
||||||
struct node *root = dti->dt;
|
struct node *root = dti->dt;
|
||||||
unsigned int cell, cellsize = 0;
|
unsigned int cell, cellsize = 0;
|
||||||
|
@ -1401,6 +1401,7 @@ static void check_property_phandle_args(struct check *c,
|
||||||
struct node *provider_node;
|
struct node *provider_node;
|
||||||
struct property *cellprop;
|
struct property *cellprop;
|
||||||
cell_t phandle;
|
cell_t phandle;
|
||||||
|
unsigned int expected;
|
||||||
|
|
||||||
phandle = propval_cell_n(prop, cell);
|
phandle = propval_cell_n(prop, cell);
|
||||||
/*
|
/*
|
||||||
|
@ -1450,10 +1451,12 @@ static void check_property_phandle_args(struct check *c,
|
||||||
break;
|
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,
|
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);
|
prop->val.len, cellsize);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -513,6 +513,9 @@ libfdt_tests () {
|
||||||
run_dtc_test -I fs -O dtb -o fs.test_tree1.test.dtb $FSBASE/test_tree1
|
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
|
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
|
# check full tests
|
||||||
for good in test_tree1.dtb; do
|
for good in test_tree1.dtb; do
|
||||||
run_test check_full $good
|
run_test check_full $good
|
||||||
|
|
Loading…
Reference in New Issue