Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

exfat: fix refcount leak in exfat_find

Fix refcount leaks in `exfat_find` related to `exfat_get_dentry_set`.

Function `exfat_get_dentry_set` would increase the reference counter of
`es->bh` on success. Therefore, `exfat_put_dentry_set` must be called
after `exfat_get_dentry_set` to ensure refcount consistency. This patch
relocate two checks to avoid possible leaks.

Fixes: 82ebecdc74ff ("exfat: fix improper check of dentry.stream.valid_size")
Fixes: 13940cef9549 ("exfat: add a check for invalid data size")
Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>

authored by

Shuhao Fu and committed by
Namjae Jeon
9aee8de9 d61f1cc5

+10 -10
+10 -10
fs/exfat/namei.c
··· 645 645 info->valid_size = le64_to_cpu(ep2->dentry.stream.valid_size); 646 646 info->size = le64_to_cpu(ep2->dentry.stream.size); 647 647 648 - if (info->valid_size < 0) { 649 - exfat_fs_error(sb, "data valid size is invalid(%lld)", info->valid_size); 650 - return -EIO; 651 - } 652 - 653 - if (unlikely(EXFAT_B_TO_CLU_ROUND_UP(info->size, sbi) > sbi->used_clusters)) { 654 - exfat_fs_error(sb, "data size is invalid(%lld)", info->size); 655 - return -EIO; 656 - } 657 - 658 648 info->start_clu = le32_to_cpu(ep2->dentry.stream.start_clu); 659 649 if (!is_valid_cluster(sbi, info->start_clu) && info->size) { 660 650 exfat_warn(sb, "start_clu is invalid cluster(0x%x)", ··· 681 691 ep->dentry.file.access_date, 682 692 0); 683 693 exfat_put_dentry_set(&es, false); 694 + 695 + if (info->valid_size < 0) { 696 + exfat_fs_error(sb, "data valid size is invalid(%lld)", info->valid_size); 697 + return -EIO; 698 + } 699 + 700 + if (unlikely(EXFAT_B_TO_CLU_ROUND_UP(info->size, sbi) > sbi->used_clusters)) { 701 + exfat_fs_error(sb, "data size is invalid(%lld)", info->size); 702 + return -EIO; 703 + } 684 704 685 705 if (ei->start_clu == EXFAT_FREE_CLUSTER) { 686 706 exfat_fs_error(sb,