Commit 18383cb9 authored by Andrzej Hajda's avatar Andrzej Hajda Committed by Inki Dae

drm/exynos/ipp: add file checks for ioctls

Process should not have access to ipp nodes created by another
process. The patch adds necessary checks.
It also simplifies lookup for command node.
Signed-off-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Reviewed-by: default avatarJoonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent d9b9734c
...@@ -318,44 +318,6 @@ static void ipp_print_property(struct drm_exynos_ipp_property *property, ...@@ -318,44 +318,6 @@ static void ipp_print_property(struct drm_exynos_ipp_property *property,
sz->hsize, sz->vsize, config->flip, config->degree); sz->hsize, sz->vsize, config->flip, config->degree);
} }
static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property)
{
struct exynos_drm_ippdrv *ippdrv;
struct drm_exynos_ipp_cmd_node *c_node;
u32 prop_id = property->prop_id;
DRM_DEBUG_KMS("prop_id[%d]\n", prop_id);
ippdrv = ipp_find_drv_by_handle(prop_id);
if (IS_ERR(ippdrv)) {
DRM_ERROR("failed to get ipp driver.\n");
return -EINVAL;
}
/*
* Find command node using command list in ippdrv.
* when we find this command no using prop_id.
* return property information set in this command node.
*/
mutex_lock(&ippdrv->cmd_lock);
list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
if ((c_node->property.prop_id == prop_id) &&
(c_node->state == IPP_STATE_STOP)) {
mutex_unlock(&ippdrv->cmd_lock);
DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n",
property->cmd, (int)ippdrv);
c_node->property = *property;
return 0;
}
}
mutex_unlock(&ippdrv->cmd_lock);
DRM_ERROR("failed to search property.\n");
return -EINVAL;
}
static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void) static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void)
{ {
struct drm_exynos_ipp_cmd_work *cmd_work; struct drm_exynos_ipp_cmd_work *cmd_work;
...@@ -391,6 +353,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, ...@@ -391,6 +353,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
struct drm_exynos_ipp_property *property = data; struct drm_exynos_ipp_property *property = data;
struct exynos_drm_ippdrv *ippdrv; struct exynos_drm_ippdrv *ippdrv;
struct drm_exynos_ipp_cmd_node *c_node; struct drm_exynos_ipp_cmd_node *c_node;
u32 prop_id;
int ret, i; int ret, i;
if (!ctx) { if (!ctx) {
...@@ -403,6 +366,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, ...@@ -403,6 +366,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
return -EINVAL; return -EINVAL;
} }
prop_id = property->prop_id;
/* /*
* This is log print for user application property. * This is log print for user application property.
* user application set various property. * user application set various property.
...@@ -411,14 +376,24 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, ...@@ -411,14 +376,24 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
ipp_print_property(property, i); ipp_print_property(property, i);
/* /*
* set property ioctl generated new prop_id. * In case prop_id is not zero try to set existing property.
* but in this case already asigned prop_id using old set property.
* e.g PAUSE state. this case supports find current prop_id and use it
* instead of allocation.
*/ */
if (property->prop_id) { if (prop_id) {
DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id); c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, prop_id);
return ipp_find_and_set_property(property);
if (!c_node || c_node->filp != file) {
DRM_DEBUG_KMS("prop_id[%d] not found\n", prop_id);
return -EINVAL;
}
if (c_node->state != IPP_STATE_STOP) {
DRM_DEBUG_KMS("prop_id[%d] not stopped\n", prop_id);
return -EINVAL;
}
c_node->property = *property;
return 0;
} }
/* find ipp driver using ipp id */ /* find ipp driver using ipp id */
...@@ -897,7 +872,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, ...@@ -897,7 +872,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
/* find command node */ /* find command node */
c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock,
qbuf->prop_id); qbuf->prop_id);
if (!c_node) { if (!c_node || c_node->filp != file) {
DRM_ERROR("failed to get command node.\n"); DRM_ERROR("failed to get command node.\n");
return -ENODEV; return -ENODEV;
} }
...@@ -1032,7 +1007,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data, ...@@ -1032,7 +1007,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock,
cmd_ctrl->prop_id); cmd_ctrl->prop_id);
if (!c_node) { if (!c_node || c_node->filp != file) {
DRM_ERROR("invalid command node list.\n"); DRM_ERROR("invalid command node list.\n");
return -ENODEV; return -ENODEV;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment