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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = -ERANGE;
|
||||||
|
|
||||||
if (phys == 0) {
|
if (phys == 0) {
|
||||||
ret = -EINVAL;
|
KGSL_CORE_ERR("kgsl_get_phys_file returned phys=0\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset >= len) {
|
/* Make sure the length of the region, the offset and the desired
|
||||||
ret = -EINVAL;
|
* 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;
|
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)
|
if (size == 0)
|
||||||
size = len;
|
size = len - offset;
|
||||||
|
|
||||||
/* Adjust the size of the region to account for the offset */
|
else if (_check_region(offset, size, len))
|
||||||
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;
|
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
entry->priv_data = filep;
|
entry->priv_data = filep;
|
||||||
|
|
||||||
entry->memdesc.pagetable = pagetable;
|
entry->memdesc.pagetable = pagetable;
|
||||||
entry->memdesc.size = size;
|
entry->memdesc.size = size;
|
||||||
entry->memdesc.physaddr = phys + (offset & PAGE_MASK);
|
entry->memdesc.physaddr = phys + offset;
|
||||||
entry->memdesc.hostptr = (void *) (virt + (offset & PAGE_MASK));
|
entry->memdesc.hostptr = (void *) (virt + offset);
|
||||||
|
|
||||||
ret = memdesc_sg_phys(&entry->memdesc,
|
ret = memdesc_sg_phys(&entry->memdesc, phys + offset, size);
|
||||||
phys + (offset & PAGE_MASK), size);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,8 @@ memdesc_sg_phys(struct kgsl_memdesc *memdesc,
|
||||||
unsigned int physaddr, unsigned int size)
|
unsigned int physaddr, unsigned int size)
|
||||||
{
|
{
|
||||||
memdesc->sg = kgsl_sg_alloc(1);
|
memdesc->sg = kgsl_sg_alloc(1);
|
||||||
|
if (!memdesc->sg)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
kmemleak_not_leak(memdesc->sg);
|
kmemleak_not_leak(memdesc->sg);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue