mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm: kgsl: improved bounds checking on user-specified parameters
Verify that the user specified length for a PMEM region is smaller than the size of the entire region as reported by the kernel APIs. Change-Id: Ic0dedbad0127bdaed70eafc00238b44f982b093b Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Iliyan Malchev <malchev@google.com>
This commit is contained in:
parent
b6c60c851b
commit
5f63a32adc
2 changed files with 31 additions and 20 deletions
|
@ -1543,42 +1543,51 @@ static int kgsl_setup_phys_file(struct kgsl_mem_entry *entry,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = -ERANGE;
|
||||
|
||||
if (phys == 0) {
|
||||
ret = -EINVAL;
|
||||
KGSL_CORE_ERR("kgsl_get_phys_file returned phys=0\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (offset >= len) {
|
||||
ret = -EINVAL;
|
||||
/* Make sure the length of the region, the offset and the desired
|
||||
* size are all page aligned or bail
|
||||
*/
|
||||
if ((len & ~PAGE_MASK) ||
|
||||
(offset & ~PAGE_MASK) ||
|
||||
(size & ~PAGE_MASK)) {
|
||||
KGSL_CORE_ERR("length %lu, offset %u or size %u "
|
||||
"is not page aligned\n",
|
||||
len, offset, size);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* The size or offset can never be greater than the PMEM length */
|
||||
if (offset >= len || size > len) {
|
||||
KGSL_CORE_ERR("offset %u or size %u "
|
||||
"exceeds pmem length %lu\n",
|
||||
offset, size, len);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* If size is 0, then adjust it to default to the size of the region
|
||||
* minus the offset. If size isn't zero, then make sure that it will
|
||||
* fit inside of the region.
|
||||
*/
|
||||
if (size == 0)
|
||||
size = len;
|
||||
size = len - offset;
|
||||
|
||||
/* Adjust the size of the region to account for the offset */
|
||||
size += offset & ~PAGE_MASK;
|
||||
|
||||
size = ALIGN(size, PAGE_SIZE);
|
||||
|
||||
if (_check_region(offset & PAGE_MASK, size, len)) {
|
||||
KGSL_CORE_ERR("Offset (%ld) + size (%d) is larger"
|
||||
"than pmem region length %ld\n",
|
||||
offset & PAGE_MASK, size, len);
|
||||
ret = -EINVAL;
|
||||
else if (_check_region(offset, size, len))
|
||||
goto err;
|
||||
|
||||
}
|
||||
|
||||
entry->priv_data = filep;
|
||||
|
||||
entry->memdesc.pagetable = pagetable;
|
||||
entry->memdesc.size = size;
|
||||
entry->memdesc.physaddr = phys + (offset & PAGE_MASK);
|
||||
entry->memdesc.hostptr = (void *) (virt + (offset & PAGE_MASK));
|
||||
entry->memdesc.physaddr = phys + offset;
|
||||
entry->memdesc.hostptr = (void *) (virt + offset);
|
||||
|
||||
ret = memdesc_sg_phys(&entry->memdesc,
|
||||
phys + (offset & PAGE_MASK), size);
|
||||
ret = memdesc_sg_phys(&entry->memdesc, phys + offset, size);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -117,6 +117,8 @@ memdesc_sg_phys(struct kgsl_memdesc *memdesc,
|
|||
unsigned int physaddr, unsigned int size)
|
||||
{
|
||||
memdesc->sg = kgsl_sg_alloc(1);
|
||||
if (!memdesc->sg)
|
||||
return -ENOMEM;
|
||||
|
||||
kmemleak_not_leak(memdesc->sg);
|
||||
|
||||
|
|
Loading…
Reference in a new issue