diff options
| author | Zhihao Cheng <chengzhihao1@huawei.com> | 2019-10-29 20:58:23 +0800 | 
|---|---|---|
| committer | Richard Weinberger <richard@nod.at> | 2019-11-17 22:22:54 +0100 | 
| commit | 10256f000932f12596dc043cf880ecf488a32510 (patch) | |
| tree | f4dcff26c9a18d61c8603ff195034ac98b5127ea | |
| parent | 91cbf01178c37086b32148c53e24b04cb77557cf (diff) | |
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>
| -rw-r--r-- | fs/ubifs/orphan.c | 17 | 
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; | 
