Browse Source

checks: fix simple-bus compatible matching

Since commit 7975f64222 ("Fix widespread incorrect use of strneq(),
replace with new strprefixeq()") simple-bus checks have been silently
skipped. The problem was 'end - str' is one more than the string length
and the strnlen in strprefixeq fails. This can't be fixed simply by
subtracting one as it is possible to have multiple '\0' at the end of
the property. Fix this by making the 'compatible' property string list
check a dependency, and then we can assume the property is null
terminated and we can just use streq() for comparisons.

Add some tests so the problem doesn't happen again.

Fixes: 7975f64222 ("Fix widespread incorrect use of strneq(), replace with new strprefixeq()")
Reported-by: Kumar Gala <kumar.gala@linaro.org>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
main
Rob Herring 6 years ago committed by David Gibson
parent
commit
e84742aa7b
  1. 5
      checks.c
  2. 4
      tests/run_tests.sh
  3. 18
      tests/unit-addr-simple-bus-compatible.dts
  4. 18
      tests/unit-addr-simple-bus-reg-mismatch.dts

5
checks.c

@ -910,7 +910,7 @@ static bool node_is_compatible(struct node *node, const char *compat) @@ -910,7 +910,7 @@ static bool node_is_compatible(struct node *node, const char *compat)

for (str = prop->val.val, end = str + prop->val.len; str < end;
str += strnlen(str, end - str) + 1) {
if (strprefixeq(str, end - str, compat))
if (streq(str, compat))
return true;
}
return false;
@ -921,7 +921,8 @@ static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct @@ -921,7 +921,8 @@ static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct
if (node_is_compatible(node, "simple-bus"))
node->bus = &simple_bus;
}
WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells);
WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL,
&addr_size_cells, &compatible_is_string_list);

static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
{

4
tests/run_tests.sh

@ -668,6 +668,10 @@ dtc_tests () { @@ -668,6 +668,10 @@ dtc_tests () {
check_tests pci-bridge-bad1.dts pci_bridge
check_tests pci-bridge-bad2.dts pci_bridge

check_tests unit-addr-simple-bus-reg-mismatch.dts simple_bus_reg
check_tests unit-addr-simple-bus-compatible.dts simple_bus_reg


# Check warning options
run_sh_test dtc-checkfails.sh address_cells_is_cell interrupt_cells_is_cell -n size_cells_is_cell -- -Wno_size_cells_is_cell -I dts -O dtb bad-ncells.dts
run_sh_test dtc-fails.sh -n test-warn-output.test.dtb -I dts -O dtb bad-ncells.dts

18
tests/unit-addr-simple-bus-compatible.dts

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
/dts-v1/;

/ {
#address-cells = <1>;
#size-cells = <1>;

bus@10000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "foo-bus", "simple-bus";
ranges = <0x0 0x10000000 0x10000>;

node@100 {
reg = <0x1000 1>;
};
};

};

18
tests/unit-addr-simple-bus-reg-mismatch.dts

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
/dts-v1/;

/ {
#address-cells = <1>;
#size-cells = <1>;

bus@10000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0x0 0x10000000 0x10000>;

node@100 {
reg = <0x1000 1>;
};
};

};
Loading…
Cancel
Save