Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55667ffd authored by Keith Fallows's avatar Keith Fallows
Browse files

fix memory corruption in map_buffer TBUG-411 TQC-24



Change-Id: I77a0e617c45221fbe328f8e123284a81a5e4ec44
Signed-off-by: default avatarSylvain Trosset <trosset.sylvain@gmail.com>
Signed-off-by: default avatarKeith Fallows <keithf@codeaurora.org>
Acked-by: default avatarTony Hamilton <tonyh@qti.qualcomm.com>
parent 487e7433
Loading
Loading
Loading
Loading
+15 −16
Original line number Original line Diff line number Diff line
@@ -347,7 +347,7 @@ static int map_buffer(struct task_struct *task, void *wsm_buffer,
	void		*virt_addr_page;
	void		*virt_addr_page;
	struct page	*page;
	struct page	*page;
	struct mmutable	*mmutable;
	struct mmutable	*mmutable;
	struct page	**mmutable_as_array_of_pointers_to_page;
	struct page	**mmutable_as_array_of_pointers_to_page = NULL;
	/* page offset in wsm buffer */
	/* page offset in wsm buffer */
	unsigned int offset;
	unsigned int offset;


@@ -384,12 +384,21 @@ static int map_buffer(struct task_struct *task, void *wsm_buffer,
	}
	}


	mmutable = table->virt;
	mmutable = table->virt;
#if (defined LPAE_SUPPORT) || !(defined CONFIG_ARM64)
	/*
	/*
	 * We use the memory for the MMU table to hold the pointer
	 * We use the memory for the MMU table to hold the pointer
	 * and convert them later. This works, as everything comes
	 * and convert them later. This works, as everything comes
	 * down to a 32 bit value.
	 * down to a 32 bit value.
	 */
	 */
	mmutable_as_array_of_pointers_to_page = (struct page **)mmutable;
	mmutable_as_array_of_pointers_to_page = (struct page **)mmutable;
#else
	mmutable_as_array_of_pointers_to_page = kmalloc(
		sizeof(struct page *)*nr_of_pages, GFP_KERNEL | __GFP_ZERO);
	if (mmutable_as_array_of_pointers_to_page == NULL) {
		ret = -ENOMEM;
		goto map_buffer_end;
	}
#endif


	/* Request comes from user space */
	/* Request comes from user space */
	if (task != NULL && !is_vmalloc_addr(wsm_buffer)) {
	if (task != NULL && !is_vmalloc_addr(wsm_buffer)) {
@@ -407,7 +416,7 @@ static int map_buffer(struct task_struct *task, void *wsm_buffer,
				 mmutable_as_array_of_pointers_to_page);
				 mmutable_as_array_of_pointers_to_page);
		if (ret != 0) {
		if (ret != 0) {
			MCDRV_DBG_ERROR(mcd, "lock_user_pages() failed");
			MCDRV_DBG_ERROR(mcd, "lock_user_pages() failed");
			return ret;
			goto map_buffer_end;
		}
		}
	}
	}
	/* Request comes from kernel space(cont buffer) */
	/* Request comes from kernel space(cont buffer) */
@@ -449,20 +458,10 @@ static int map_buffer(struct task_struct *task, void *wsm_buffer,
	 * - or fails and used_mmutable->table contains the list of page
	 * - or fails and used_mmutable->table contains the list of page
	 * pointers.
	 * pointers.
	 * Any mixed contents will make cleanup difficult.
	 * Any mixed contents will make cleanup difficult.
	 */
#if defined(CONFIG_ARM64) && !defined(LPAE_SUPPORT)
	/*
	 * When NWd pointers are 64bits and SWd pte 32bits we need to fill the
	 * table from 0.
	 */
	i = 0;
#else
	/*
	 * Fill the table in reverse order as the table is used as input and
	 * Fill the table in reverse order as the table is used as input and
	 * output.
	 * output.
	 */
	 */
	i = MC_ARM_MMU_TABLE_ENTRIES-1;
	i = MC_ARM_MMU_TABLE_ENTRIES-1;
#endif
	do {
	do {
		if (i < nr_of_pages) {
		if (i < nr_of_pages) {
#ifdef LPAE_SUPPORT
#ifdef LPAE_SUPPORT
@@ -521,12 +520,12 @@ static int map_buffer(struct task_struct *task, void *wsm_buffer,
			/* ensure rest of table is empty */
			/* ensure rest of table is empty */
			mmutable->table_entries[i] = 0;
			mmutable->table_entries[i] = 0;
		}
		}
#if defined(CONFIG_ARM64) && !defined(LPAE_SUPPORT)
	} while (++i < MC_ARM_MMU_TABLE_ENTRIES);
#else
	} while (i-- != 0);
	} while (i-- != 0);
#endif


map_buffer_end:
#if !(defined LPAE_SUPPORT) && (defined CONFIG_ARM64)
	kfree(mmutable_as_array_of_pointers_to_page);
#endif
	return ret;
	return ret;
}
}