mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
scsi: target: tcmu: Fix possible page UAF
[ Upstream commit a6968f7a36 ]
tcmu_try_get_data_page() looks up pages under cmdr_lock, but it does not
take refcount properly and just returns page pointer. When
tcmu_try_get_data_page() returns, the returned page may have been freed by
tcmu_blocks_release().
We need to get_page() under cmdr_lock to avoid concurrent
tcmu_blocks_release().
Link: https://lore.kernel.org/r/20220311132206.24515-1-xiaoguang.wang@linux.alibaba.com
Reviewed-by: Bodo Stroesser <bostroesser@gmail.com>
Signed-off-by: Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
4366679805
commit
aec36b98a1
@@ -1676,6 +1676,7 @@ static struct page *tcmu_try_get_block_page(struct tcmu_dev *udev, uint32_t dbi)
|
|||||||
mutex_lock(&udev->cmdr_lock);
|
mutex_lock(&udev->cmdr_lock);
|
||||||
page = tcmu_get_block_page(udev, dbi);
|
page = tcmu_get_block_page(udev, dbi);
|
||||||
if (likely(page)) {
|
if (likely(page)) {
|
||||||
|
get_page(page);
|
||||||
mutex_unlock(&udev->cmdr_lock);
|
mutex_unlock(&udev->cmdr_lock);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
@@ -1714,6 +1715,7 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf)
|
|||||||
/* For the vmalloc()ed cmd area pages */
|
/* For the vmalloc()ed cmd area pages */
|
||||||
addr = (void *)(unsigned long)info->mem[mi].addr + offset;
|
addr = (void *)(unsigned long)info->mem[mi].addr + offset;
|
||||||
page = vmalloc_to_page(addr);
|
page = vmalloc_to_page(addr);
|
||||||
|
get_page(page);
|
||||||
} else {
|
} else {
|
||||||
uint32_t dbi;
|
uint32_t dbi;
|
||||||
|
|
||||||
@@ -1724,7 +1726,6 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf)
|
|||||||
return VM_FAULT_SIGBUS;
|
return VM_FAULT_SIGBUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_page(page);
|
|
||||||
vmf->page = page;
|
vmf->page = page;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user