Skip to content

Commit

Permalink
Handle integer overflow in check_property_phandle_args()
Browse files Browse the repository at this point in the history
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 #64

Reported-by: Anciety <anciety@pku.edu.cn>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
  • Loading branch information
dgibson committed Dec 29, 2021
1 parent ca72944 commit ff5afb9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
15 changes: 9 additions & 6 deletions checks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
/*
Expand Down Expand Up @@ -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;
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions tests/phandle-args-overflow.dts
Original file line number Diff line number Diff line change
@@ -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 changes: 3 additions & 0 deletions tests/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ff5afb9

Please sign in to comment.