summaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2019-10-29 20:58:23 +0800
committerRichard Weinberger <richard@nod.at>2019-11-17 22:22:54 +0100
commit10256f000932f12596dc043cf880ecf488a32510 (patch)
treef4dcff26c9a18d61c8603ff195034ac98b5127ea /fs/ubifs
parent91cbf01178c37086b32148c53e24b04cb77557cf (diff)
downloadlinux-10256f000932f12596dc043cf880ecf488a32510.tar.gz
linux-10256f000932f12596dc043cf880ecf488a32510.tar.bz2
linux-10256f000932f12596dc043cf880ecf488a32510.zip
ubifs: do_kill_orphans: Fix a memory leak bug
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>
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/orphan.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index 3b4b4114f208..54d6db61106f 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -631,12 +631,17 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
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_info *c, struct ubifs_scan_leb *sleb,
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;