tcmu: prevent corruption when invalid data page requested

"Linux Kernel Mailing List" <[email protected]>
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/c1c390ba53195aef36e94b2354bc0e603057c293
Commit:     c1c390ba53195aef36e94b2354bc0e603057c293
Parent:     9960f85181dd08cda03fddcf0bc8d81190bec4eb
Refname:    refs/heads/master
Author:     Mike Christie <[email protected]>
AuthorDate: Tue Dec 19 04:03:54 2017 -0600
Committer:  Nicholas Bellinger <[email protected]>
CommitDate: Fri Jan 12 15:07:29 2018 -0800

    tcmu: prevent corruption when invalid data page requested
    
    We will always have a page mapped for cmd data if it is
    valid command. If the mapping does not exist then something
    bad happened in userspace and it should not proceed. This
    has us return VM_FAULT_SIGBUS when this happens instead of
    returning a freshly allocated paged. The latter can cause
    corruption because userspace might write the pages data
    overwriting valid data or return it to the initiator.
    
    Signed-off-by: Mike Christie <[email protected]>
    Signed-off-by: Nicholas Bellinger <[email protected]>
---
 drivers/target/target_core_user.c | 43 ++++++---------------------------------
 1 file changed, 6 insertions(+), 37 deletions(-)

diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index bac08bc72e3b..a746fedbb486 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1342,7 +1342,6 @@ static int tcmu_find_mem_index(struct vm_area_struct *vma)
 static struct page *tcmu_try_get_block_page(struct tcmu_dev *udev, uint32_t dbi)
 {
 	struct page *page;
-	int ret;
 
 	mutex_lock(&udev->cmdr_lock);
 	page = tcmu_get_block_page(udev, dbi);
@@ -1352,42 +1351,12 @@ static struct page *tcmu_try_get_block_page(struct tcmu_dev *udev, uint32_t dbi)
 	}
 
 	/*
-	 * Normally it shouldn't be here:
-	 * Only when the userspace has touched the blocks which
-	 * are out of the tcmu_cmd's data iov[], and will return
-	 * one zeroed page.
+	 * Userspace messed up and passed in a address not in the
+	 * data iov passed to it.
 	 */
-	pr_warn("Block(%u) out of cmd's iov[] has been touched!\n", dbi);
-	pr_warn("Mostly it will be a bug of userspace, please have a check!\n");
-
-	if (dbi >= udev->dbi_thresh) {
-		/* Extern the udev->dbi_thresh to dbi + 1 */
-		udev->dbi_thresh = dbi + 1;
-		udev->dbi_max = dbi;
-	}
-
-	page = radix_tree_lookup(&udev->data_blocks, dbi);
-	if (!page) {
-		page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-		if (!page) {
-			mutex_unlock(&udev->cmdr_lock);
-			return NULL;
-		}
-
-		ret = radix_tree_insert(&udev->data_blocks, dbi, page);
-		if (ret) {
-			mutex_unlock(&udev->cmdr_lock);
-			__free_page(page);
-			return NULL;
-		}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.