summaryrefslogtreecommitdiff
path: root/drivers/media/pci/intel
diff options
context:
space:
mode:
authorYong Zhi <yong.zhi@intel.com>2018-01-03 21:57:16 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2018-01-05 12:43:20 -0500
commitc7cbef1fdb5480e9f39e8db64ac32ed8e1984adf (patch)
tree86db2077e8387e8174b9d838ad000812334792b8 /drivers/media/pci/intel
parent883dd4c1b8d95c78158a993fc383bfbf5463a095 (diff)
media: intel-ipu3: cio2: fix a crash with out-of-bounds access
When dmabuf is used for BLOB type frame, the frame buffers allocated by gralloc will hold more pages than the valid frame data due to height alignment. In this case, the page numbers in sg list could exceed the FBPT upper limit value - max_lops(8)*1024 to cause crash. Limit the LOP access to the valid data length to avoid FBPT sub-entries overflow. Signed-off-by: Yong Zhi <yong.zhi@intel.com> Signed-off-by: Cao Bing Bu <bingbu.cao@intel.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/pci/intel')
-rw-r--r--drivers/media/pci/intel/ipu3/ipu3-cio2.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
index 9b9ad7771dda..9377f880b8f6 100644
--- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -838,8 +838,9 @@ static int cio2_vb2_buf_init(struct vb2_buffer *vb)
container_of(vb, struct cio2_buffer, vbb.vb2_buf);
static const unsigned int entries_per_page =
CIO2_PAGE_SIZE / sizeof(u32);
- unsigned int pages = DIV_ROUND_UP(vb->planes[0].length, CIO2_PAGE_SIZE);
- unsigned int lops = DIV_ROUND_UP(pages + 1, entries_per_page);
+ unsigned int pages = DIV_ROUND_UP(vb->planes[0].length,
+ CIO2_PAGE_SIZE) + 1;
+ unsigned int lops = DIV_ROUND_UP(pages, entries_per_page);
struct sg_table *sg;
struct sg_page_iter sg_iter;
int i, j;
@@ -869,6 +870,8 @@ static int cio2_vb2_buf_init(struct vb2_buffer *vb)
i = j = 0;
for_each_sg_page(sg->sgl, &sg_iter, sg->nents, 0) {
+ if (!pages--)
+ break;
b->lop[i][j] = sg_page_iter_dma_address(&sg_iter) >> PAGE_SHIFT;
j++;
if (j == entries_per_page) {