Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mtd: parsers: ofpart: fix OF node refcount leak in parse_fixed_partitions()

of_get_child_by_name() returns a node pointer with refcount incremented,
which must be released with of_node_put() when done. However, in
parse_fixed_partitions(), when dedicated is true (i.e., a "partitions"
subnode was found), the ofpart_node obtained from of_get_child_by_name()
is never released on any code path.

Add of_node_put(ofpart_node) calls on all exit paths when dedicated is
true to fix the reference count leak.

This bug was detected by our static analysis tool.

Fixes: 562b4e91d3b2 ("mtd: parsers: ofpart: fix parsing subpartitions")
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

authored by

Weigang He and committed by
Miquel Raynal
7cce81df 68cd8ef4

+14 -2
+14 -2
drivers/mtd/parsers/ofpart_core.c
··· 81 81 of_id = of_match_node(parse_ofpart_match_table, ofpart_node); 82 82 if (dedicated && !of_id) { 83 83 /* The 'partitions' subnode might be used by another parser */ 84 + of_node_put(ofpart_node); 84 85 return 0; 85 86 } 86 87 ··· 96 95 nr_parts++; 97 96 } 98 97 99 - if (nr_parts == 0) 98 + if (nr_parts == 0) { 99 + if (dedicated) 100 + of_node_put(ofpart_node); 100 101 return 0; 102 + } 101 103 102 104 parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); 103 - if (!parts) 105 + if (!parts) { 106 + if (dedicated) 107 + of_node_put(ofpart_node); 104 108 return -ENOMEM; 109 + } 105 110 106 111 i = 0; 107 112 for_each_child_of_node(ofpart_node, pp) { ··· 186 179 if (quirks && quirks->post_parse) 187 180 quirks->post_parse(master, parts, nr_parts); 188 181 182 + if (dedicated) 183 + of_node_put(ofpart_node); 184 + 189 185 *pparts = parts; 190 186 return nr_parts; 191 187 ··· 197 187 master->name, pp, mtd_node); 198 188 ret = -EINVAL; 199 189 ofpart_none: 190 + if (dedicated) 191 + of_node_put(ofpart_node); 200 192 of_node_put(pp); 201 193 kfree(parts); 202 194 return ret;