Message ID | 1574363816-13981-1-git-send-email-frowand.list@gmail.com |
---|---|
State | Accepted, archived |
Headers | show |
Series | of: overlay: add_changeset_property() memory leak | expand |
Context | Check | Description |
---|---|---|
robh/checkpatch | success |
Hi Vincent, On 11/21/19 1:16 PM, frowand.list@gmail.com wrote: > From: Frank Rowand <frank.rowand@sony.com> > > No changeset entries are created for #address-cells and #size-cells > properties, but the duplicated properties are never freed. This > results in a memory leak which is detected by kmemleak: > > unreferenced object 0x85887180 (size 64): > backtrace: > kmem_cache_alloc_trace+0x1fb/0x1fc > __of_prop_dup+0x25/0x7c > add_changeset_property+0x17f/0x370 > build_changeset_next_level+0x29/0x20c > of_overlay_fdt_apply+0x32b/0x6b4 > ... > > Fixes: 6f75118800acf77f8 ("of: overlay: validate overlay properties #address-cells and #size-cells") > Reported-by: Vincent Whitchurch <vincent.whitchurch@axis.com> > Signed-off-by: Frank Rowand <frank.rowand@sony.com> > --- > drivers/of/overlay.c | 37 ++++++++++++++++++++----------------- > 1 file changed, 20 insertions(+), 17 deletions(-) > > diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c > index c423e94baf0f..9617b7df7c4d 100644 > --- a/drivers/of/overlay.c > +++ b/drivers/of/overlay.c > @@ -305,7 +305,6 @@ static int add_changeset_property(struct overlay_changeset *ovcs, > { > struct property *new_prop = NULL, *prop; > int ret = 0; > - bool check_for_non_overlay_node = false; > > if (target->in_livetree) > if (!of_prop_cmp(overlay_prop->name, "name") || > @@ -318,6 +317,25 @@ static int add_changeset_property(struct overlay_changeset *ovcs, > else > prop = NULL; > > + if (prop) { > + if (!of_prop_cmp(prop->name, "#address-cells")) { > + if (!of_prop_val_eq(prop, overlay_prop)) { > + pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n", > + target->np); > + ret = -EINVAL; > + } > + return ret; > + > + } else if (!of_prop_cmp(prop->name, "#size-cells")) { > + if (!of_prop_val_eq(prop, overlay_prop)) { > + pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n", > + target->np); > + ret = -EINVAL; > + } > + return ret; > + } > + } > + > if (is_symbols_prop) { > if (prop) > return -EINVAL; > @@ -330,33 +348,18 @@ static int add_changeset_property(struct overlay_changeset *ovcs, > return -ENOMEM; > > if (!prop) { > - check_for_non_overlay_node = true; > if (!target->in_livetree) { > new_prop->next = target->np->deadprops; > target->np->deadprops = new_prop; > } > ret = of_changeset_add_property(&ovcs->cset, target->np, > new_prop); > - } else if (!of_prop_cmp(prop->name, "#address-cells")) { > - if (!of_prop_val_eq(prop, new_prop)) { > - pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n", > - target->np); > - ret = -EINVAL; > - } > - } else if (!of_prop_cmp(prop->name, "#size-cells")) { > - if (!of_prop_val_eq(prop, new_prop)) { > - pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n", > - target->np); > - ret = -EINVAL; > - } > } else { > - check_for_non_overlay_node = true; > ret = of_changeset_update_property(&ovcs->cset, target->np, > new_prop); > } > > - if (check_for_non_overlay_node && > - !of_node_check_flag(target->np, OF_OVERLAY)) > + if (!of_node_check_flag(target->np, OF_OVERLAY)) > pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n", > target->np, new_prop->name); > > Can you please check whether this patch fixes the memleak that you found and fixed in "[PATCH 1/2] of: overlay: fix properties memory leak"? Thanks, Frank
On Thu, Nov 21, 2019 at 08:20:21PM +0100, Frank Rowand wrote: > On 11/21/19 1:16 PM, frowand.list@gmail.com wrote: > > From: Frank Rowand <frank.rowand@sony.com> > > > > No changeset entries are created for #address-cells and #size-cells > > properties, but the duplicated properties are never freed. This > > results in a memory leak which is detected by kmemleak: > > > > unreferenced object 0x85887180 (size 64): > > backtrace: > > kmem_cache_alloc_trace+0x1fb/0x1fc > > __of_prop_dup+0x25/0x7c > > add_changeset_property+0x17f/0x370 > > build_changeset_next_level+0x29/0x20c > > of_overlay_fdt_apply+0x32b/0x6b4 > > ... > > > > Fixes: 6f75118800acf77f8 ("of: overlay: validate overlay properties #address-cells and #size-cells") > > Reported-by: Vincent Whitchurch <vincent.whitchurch@axis.com> > > Signed-off-by: Frank Rowand <frank.rowand@sony.com> > > Can you please check whether this patch fixes the memleak that you > found and fixed in "[PATCH 1/2] of: overlay: fix properties memory leak"? Tested-by: Vincent Whitchurch <vincent.whitchurch@axis.com> Thanks.
On Thu, 21 Nov 2019 13:16:56 -0600, frowand.list@gmail.com wrote: > From: Frank Rowand <frank.rowand@sony.com> > > No changeset entries are created for #address-cells and #size-cells > properties, but the duplicated properties are never freed. This > results in a memory leak which is detected by kmemleak: > > unreferenced object 0x85887180 (size 64): > backtrace: > kmem_cache_alloc_trace+0x1fb/0x1fc > __of_prop_dup+0x25/0x7c > add_changeset_property+0x17f/0x370 > build_changeset_next_level+0x29/0x20c > of_overlay_fdt_apply+0x32b/0x6b4 > ... > > Fixes: 6f75118800acf77f8 ("of: overlay: validate overlay properties #address-cells and #size-cells") > Reported-by: Vincent Whitchurch <vincent.whitchurch@axis.com> > Signed-off-by: Frank Rowand <frank.rowand@sony.com> > --- > drivers/of/overlay.c | 37 ++++++++++++++++++++----------------- > 1 file changed, 20 insertions(+), 17 deletions(-) > Applied, thanks. Rob
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index c423e94baf0f..9617b7df7c4d 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -305,7 +305,6 @@ static int add_changeset_property(struct overlay_changeset *ovcs, { struct property *new_prop = NULL, *prop; int ret = 0; - bool check_for_non_overlay_node = false; if (target->in_livetree) if (!of_prop_cmp(overlay_prop->name, "name") || @@ -318,6 +317,25 @@ static int add_changeset_property(struct overlay_changeset *ovcs, else prop = NULL; + if (prop) { + if (!of_prop_cmp(prop->name, "#address-cells")) { + if (!of_prop_val_eq(prop, overlay_prop)) { + pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n", + target->np); + ret = -EINVAL; + } + return ret; + + } else if (!of_prop_cmp(prop->name, "#size-cells")) { + if (!of_prop_val_eq(prop, overlay_prop)) { + pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n", + target->np); + ret = -EINVAL; + } + return ret; + } + } + if (is_symbols_prop) { if (prop) return -EINVAL; @@ -330,33 +348,18 @@ static int add_changeset_property(struct overlay_changeset *ovcs, return -ENOMEM; if (!prop) { - check_for_non_overlay_node = true; if (!target->in_livetree) { new_prop->next = target->np->deadprops; target->np->deadprops = new_prop; } ret = of_changeset_add_property(&ovcs->cset, target->np, new_prop); - } else if (!of_prop_cmp(prop->name, "#address-cells")) { - if (!of_prop_val_eq(prop, new_prop)) { - pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n", - target->np); - ret = -EINVAL; - } - } else if (!of_prop_cmp(prop->name, "#size-cells")) { - if (!of_prop_val_eq(prop, new_prop)) { - pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n", - target->np); - ret = -EINVAL; - } } else { - check_for_non_overlay_node = true; ret = of_changeset_update_property(&ovcs->cset, target->np, new_prop); } - if (check_for_non_overlay_node && - !of_node_check_flag(target->np, OF_OVERLAY)) + if (!of_node_check_flag(target->np, OF_OVERLAY)) pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n", target->np, new_prop->name);