From: Zhihao Cheng chengzhihao1@huawei.com
commit 10256f000932f12596dc043cf880ecf488a32510 upstream.
If there are more than one valid snod on the sleb->nodes list, do_kill_orphans will malloc ino more than once without releasing previous ino's memory. Finally, it will trigger memory leak.
Fixes: ee1438ce5dc4 ("ubifs: Check link count of inodes when...") Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Signed-off-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ubifs/orphan.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
--- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -631,12 +631,17 @@ static int do_kill_orphans(struct ubifs_ ino_t inum; int i, n, err, first = 1;
+ ino = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS); + if (!ino) + return -ENOMEM; + list_for_each_entry(snod, &sleb->nodes, list) { if (snod->type != UBIFS_ORPH_NODE) { ubifs_err(c, "invalid node type %d in orphan area at %d:%d", snod->type, sleb->lnum, snod->offs); ubifs_dump_node(c, snod->node); - return -EINVAL; + err = -EINVAL; + goto out_free; }
orph = snod->node; @@ -663,20 +668,18 @@ static int do_kill_orphans(struct ubifs_ ubifs_err(c, "out of order commit number %llu in orphan node at %d:%d", cmt_no, sleb->lnum, snod->offs); ubifs_dump_node(c, snod->node); - return -EINVAL; + err = -EINVAL; + goto out_free; } dbg_rcvry("out of date LEB %d", sleb->lnum); *outofdate = 1; - return 0; + err = 0; + goto out_free; }
if (first) first = 0;
- ino = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS); - if (!ino) - return -ENOMEM; - n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3; for (i = 0; i < n; i++) { union ubifs_key key1, key2;