Commit df9b6a9c authored by Seung-Woo Kim's avatar Seung-Woo Kim Committed by Dave Airlie

drm: fix error routines in drm_open_helper

There are missing parts to handle error in drm_open_helper().
The priv->minor, assigned by idr_find() which can return NULL,
should be checked whether it is NULL or not before referencing it.
put_pid(), drm_gem_release(), and drm_prime_destory_file_private()
should be called when error happens after their pair functions are
called. If an error occurs after executing dev->driver->open()
which allocates driver specific per-file private data, then the
private data should be released.
Signed-off-by: default avatarYoungJun Cho <yj44.cho@samsung.com>
Signed-off-by: default avatarSeung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Chris Wilson <chris-wilson.co.uk>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent fe2ef780
...@@ -271,6 +271,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, ...@@ -271,6 +271,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
priv->uid = current_euid(); priv->uid = current_euid();
priv->pid = get_pid(task_pid(current)); priv->pid = get_pid(task_pid(current));
priv->minor = idr_find(&drm_minors_idr, minor_id); priv->minor = idr_find(&drm_minors_idr, minor_id);
if (!priv->minor) {
ret = -ENODEV;
goto out_put_pid;
}
priv->ioctl_count = 0; priv->ioctl_count = 0;
/* for compatibility root is always authenticated */ /* for compatibility root is always authenticated */
priv->authenticated = capable(CAP_SYS_ADMIN); priv->authenticated = capable(CAP_SYS_ADMIN);
...@@ -292,7 +297,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, ...@@ -292,7 +297,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
if (dev->driver->open) { if (dev->driver->open) {
ret = dev->driver->open(dev, priv); ret = dev->driver->open(dev, priv);
if (ret < 0) if (ret < 0)
goto out_free; goto out_prime_destroy;
} }
...@@ -304,7 +309,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, ...@@ -304,7 +309,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
if (!priv->minor->master) { if (!priv->minor->master) {
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
ret = -ENOMEM; ret = -ENOMEM;
goto out_free; goto out_close;
} }
priv->is_master = 1; priv->is_master = 1;
...@@ -322,7 +327,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, ...@@ -322,7 +327,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
drm_master_put(&priv->minor->master); drm_master_put(&priv->minor->master);
drm_master_put(&priv->master); drm_master_put(&priv->master);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
goto out_free; goto out_close;
} }
} }
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
...@@ -333,7 +338,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, ...@@ -333,7 +338,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
drm_master_put(&priv->minor->master); drm_master_put(&priv->minor->master);
drm_master_put(&priv->master); drm_master_put(&priv->master);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
goto out_free; goto out_close;
} }
} }
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
...@@ -367,7 +372,17 @@ static int drm_open_helper(struct inode *inode, struct file *filp, ...@@ -367,7 +372,17 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
#endif #endif
return 0; return 0;
out_free:
out_close:
if (dev->driver->postclose)
dev->driver->postclose(dev, priv);
out_prime_destroy:
if (drm_core_check_feature(dev, DRIVER_PRIME))
drm_prime_destroy_file_private(&priv->prime);
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, priv);
out_put_pid:
put_pid(priv->pid);
kfree(priv); kfree(priv);
filp->private_data = NULL; filp->private_data = NULL;
return ret; return ret;
......
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