提交 e44bf6b7 编写于 作者: B Beata Michalska 提交者: Inki Dae

drm/exynos/ipp: Validate buffer enqueue requests

As for now there is no validation of incoming buffer
enqueue request as far as the gem buffers are being
concerned. This might lead to some undesired cases
when the driver tries to operate on invalid buffers
(wiht no valid gem object handle i.e.).
Add some basic checks to rule out those potential issues.
Signed-off-by: NBeata Michalska <b.michalska@samsung.com>
[mszyprow: rebased onto v4.0-rc1 and adapted to recent ipp changes]
Signed-off-by: NMarek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: NInki Dae <inki.dae@samsung.com>
上级 e752747b
...@@ -476,6 +476,45 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, ...@@ -476,6 +476,45 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
return ret; return ret;
} }
static int ipp_validate_mem_node(struct drm_device *drm_dev,
struct drm_exynos_ipp_mem_node *m_node,
struct drm_exynos_ipp_cmd_node *c_node)
{
struct drm_exynos_ipp_config *ipp_cfg;
unsigned int num_plane;
unsigned long min_size, size;
unsigned int bpp;
int i;
/* The property id should already be varified */
ipp_cfg = &c_node->property.config[m_node->prop_id];
num_plane = drm_format_num_planes(ipp_cfg->fmt);
/**
* This is a rather simplified validation of a memory node.
* It basically verifies provided gem object handles
* and the buffer sizes with respect to current configuration.
* This is not the best that can be done
* but it seems more than enough
*/
for (i = 0; i < num_plane; ++i) {
if (!m_node->buf_info.handles[i]) {
DRM_ERROR("invalid handle for plane %d\n", i);
return -EINVAL;
}
bpp = drm_format_plane_cpp(ipp_cfg->fmt, i);
min_size = (ipp_cfg->sz.hsize * ipp_cfg->sz.vsize * bpp) >> 3;
size = exynos_drm_gem_get_size(drm_dev,
m_node->buf_info.handles[i],
c_node->filp);
if (min_size > size) {
DRM_ERROR("invalid size for plane %d\n", i);
return -EINVAL;
}
}
return 0;
}
static int ipp_put_mem_node(struct drm_device *drm_dev, static int ipp_put_mem_node(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_cmd_node *c_node,
struct drm_exynos_ipp_mem_node *m_node) struct drm_exynos_ipp_mem_node *m_node)
...@@ -552,6 +591,11 @@ static struct drm_exynos_ipp_mem_node ...@@ -552,6 +591,11 @@ static struct drm_exynos_ipp_mem_node
} }
mutex_lock(&c_node->mem_lock); mutex_lock(&c_node->mem_lock);
if (ipp_validate_mem_node(drm_dev, m_node, c_node)) {
ipp_put_mem_node(drm_dev, c_node, m_node);
mutex_unlock(&c_node->mem_lock);
return ERR_PTR(-EFAULT);
}
list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]); list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]);
mutex_unlock(&c_node->mem_lock); mutex_unlock(&c_node->mem_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册