mirror of
https://github.com/dgibson/dtc.git
synced 2025-12-07 05:35:07 -05:00
checks: Fix crash in graph_child_address if 'reg' cell size != 1
If an endpoint node has a 'reg' property which consists of more than
one cell (4 bytes) and given that matching '#address-cells' and '#size-cells'
properties are specified on the port node an assertion is triggered in
check_graph_child_address() before the relevant diagnostic checks in
check_graph_reg() (called by check_graph_port() and check_graph_endpoint()) are executed.
The issue is fixed by making graph_child_address depend on the
graph_port and graph_endpoint checks.
Additionally the assertion can also be triggered if the length of the
'reg' property is less than 4 bytes e.g. by specifying
'reg = "a";'. In that case however other warnings are produced
highlighting the malformed property before dtc crashes.
Example dts file triggering the issue:
/dts-v1/;
/ {
bar: bar {
port {
bar_con: endpoint {
remote-endpoint = <&foo_con>;
};
};
};
foo {
port {
#address-cells = <1>;
#size-cells = <1>; // should always be 0
foo_con: endpoint@1 {
reg = <1 2>; // causes assertion failure instead of diagnostic
remote-endpoint = <&bar_con>;
};
};
};
};
Signed-off-by: Johannes Beisswenger <johannes.beisswenger@cetitec.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
b2b9671583
commit
ea3b9a1d2c
1 changed files with 25 additions and 25 deletions
50
checks.c
50
checks.c
|
|
@ -1785,31 +1785,6 @@ static void check_graph_nodes(struct check *c, struct dt_info *dti,
|
|||
}
|
||||
WARNING(graph_nodes, check_graph_nodes, NULL);
|
||||
|
||||
static void check_graph_child_address(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
int cnt = 0;
|
||||
struct node *child;
|
||||
|
||||
if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus)
|
||||
return;
|
||||
|
||||
for_each_child(node, child) {
|
||||
struct property *prop = get_property(child, "reg");
|
||||
|
||||
/* No error if we have any non-zero unit address */
|
||||
if (prop && propval_cell(prop) != 0)
|
||||
return;
|
||||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (cnt == 1 && node->addr_cells != -1)
|
||||
FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary",
|
||||
node->children->name);
|
||||
}
|
||||
WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes);
|
||||
|
||||
static void check_graph_reg(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
|
|
@ -1900,6 +1875,31 @@ static void check_graph_endpoint(struct check *c, struct dt_info *dti,
|
|||
}
|
||||
WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes);
|
||||
|
||||
static void check_graph_child_address(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
int cnt = 0;
|
||||
struct node *child;
|
||||
|
||||
if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus)
|
||||
return;
|
||||
|
||||
for_each_child(node, child) {
|
||||
struct property *prop = get_property(child, "reg");
|
||||
|
||||
/* No error if we have any non-zero unit address */
|
||||
if (prop && propval_cell(prop) != 0 )
|
||||
return;
|
||||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (cnt == 1 && node->addr_cells != -1)
|
||||
FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary",
|
||||
node->children->name);
|
||||
}
|
||||
WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes, &graph_port, &graph_endpoint);
|
||||
|
||||
static struct check *check_table[] = {
|
||||
&duplicate_node_names, &duplicate_property_names,
|
||||
&node_name_chars, &node_name_format, &property_name_chars,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue