mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
scsi: target: tcmu: Fix possible page UAF
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>
This commit is contained in:
parent
ebfe3e0c5e
commit
a6968f7a36
@ -1821,6 +1821,7 @@ static struct page *tcmu_try_get_data_page(struct tcmu_dev *udev, uint32_t dpi)
|
||||
mutex_lock(&udev->cmdr_lock);
|
||||
page = xa_load(&udev->data_pages, dpi);
|
||||
if (likely(page)) {
|
||||
get_page(page);
|
||||
mutex_unlock(&udev->cmdr_lock);
|
||||
return page;
|
||||
}
|
||||
@ -1877,6 +1878,7 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf)
|
||||
/* For the vmalloc()ed cmd area pages */
|
||||
addr = (void *)(unsigned long)info->mem[mi].addr + offset;
|
||||
page = vmalloc_to_page(addr);
|
||||
get_page(page);
|
||||
} else {
|
||||
uint32_t dpi;
|
||||
|
||||
@ -1887,7 +1889,6 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf)
|
||||
return VM_FAULT_SIGBUS;
|
||||
}
|
||||
|
||||
get_page(page);
|
||||
vmf->page = page;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user