Browse Source

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
David Gibson 3 years ago
parent
commit
ff5afb96d0
  1. 15
      checks.c
  2. 18
      tests/phandle-args-overflow.dts
  3. 3
      tests/run_tests.sh

15
checks.c

@ -1382,10 +1382,10 @@ struct provider { @@ -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, @@ -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, @@ -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;
}
}
}

18
tests/phandle-args-overflow.dts

@ -0,0 +1,18 @@ @@ -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>;
};
};

3
tests/run_tests.sh

@ -513,6 +513,9 @@ libfdt_tests () { @@ -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

Loading…
Cancel
Save