summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Whitchurch <vincent.whitchurch@axis.com>2023-07-18 14:41:45 +0200
committerRichard Weinberger <richard@nod.at>2023-10-28 22:09:03 +0200
commitf4a04c97fb3b7edd7694e725b7dcf0d6901ebcdd (patch)
tree3d6f2002fabab571862783279bb2f73c20c72c80
parent48ec6328de6c153a64474d9e5b6ec95f20f4142b (diff)
downloadlinux-stable-f4a04c97fb3b7edd7694e725b7dcf0d6901ebcdd.tar.gz
linux-stable-f4a04c97fb3b7edd7694e725b7dcf0d6901ebcdd.tar.bz2
linux-stable-f4a04c97fb3b7edd7694e725b7dcf0d6901ebcdd.zip
ubifs: Fix memory leak of bud->log_hash
Ensure that the allocated bud->log_hash (if any) is freed in all cases when the bud itself is freed, to fix this leak caught by kmemleak: # keyctl add logon foo:bar data @s # echo clear > /sys/kernel/debug/kmemleak # mount -t ubifs /dev/ubi0_0 mnt -o auth_hash_name=sha256,auth_key=foo:bar # echo a > mnt/x # umount mnt # mount -t ubifs /dev/ubi0_0 mnt -o auth_hash_name=sha256,auth_key=foo:bar # umount mnt # sleep 5 # echo scan > /sys/kernel/debug/kmemleak # echo scan > /sys/kernel/debug/kmemleak # cat /sys/kernel/debug/kmemleak unreferenced object 0xff... (size 128): comm "mount" backtrace: __kmalloc __ubifs_hash_get_desc+0x5d/0xe0 ubifs ubifs_replay_journal ubifs_mount ... Fixes: da8ef65f9573 ("ubifs: Authenticate replayed journal") Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com> Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r--fs/ubifs/super.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index b08fb28d16b5..610dddc68eba 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -923,8 +923,10 @@ static void free_buds(struct ubifs_info *c)
{
struct ubifs_bud *bud, *n;
- rbtree_postorder_for_each_entry_safe(bud, n, &c->buds, rb)
+ rbtree_postorder_for_each_entry_safe(bud, n, &c->buds, rb) {
+ kfree(bud->log_hash);
kfree(bud);
+ }
}
/**
@@ -1193,6 +1195,7 @@ static void destroy_journal(struct ubifs_info *c)
bud = list_entry(c->old_buds.next, struct ubifs_bud, list);
list_del(&bud->list);
+ kfree(bud->log_hash);
kfree(bud);
}
ubifs_destroy_idx_gc(c);