Commit 3a9df1e9 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-fixes-2018-10-04' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

drm-misc-fixes for v4.19-rc7:
- Fix use-after-free in drm_mode_create_lease_ioctl()
- Fix crash in fbdev error path.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/13b2c3ac-9a96-710e-ceb9-890af164f10e@linux.intel.com
parents d8938c98 4d4c2d89
......@@ -63,20 +63,21 @@ static void drm_client_close(struct drm_client_dev *client)
EXPORT_SYMBOL(drm_client_close);
/**
* drm_client_new - Create a DRM client
* drm_client_init - Initialise a DRM client
* @dev: DRM device
* @client: DRM client
* @name: Client name
* @funcs: DRM client functions (optional)
*
* This initialises the client and opens a &drm_file. Use drm_client_add() to complete the process.
* The caller needs to hold a reference on @dev before calling this function.
* The client is freed when the &drm_device is unregistered. See drm_client_release().
*
* Returns:
* Zero on success or negative error code on failure.
*/
int drm_client_new(struct drm_device *dev, struct drm_client_dev *client,
const char *name, const struct drm_client_funcs *funcs)
int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
const char *name, const struct drm_client_funcs *funcs)
{
int ret;
......@@ -95,10 +96,6 @@ int drm_client_new(struct drm_device *dev, struct drm_client_dev *client,
if (ret)
goto err_put_module;
mutex_lock(&dev->clientlist_mutex);
list_add(&client->list, &dev->clientlist);
mutex_unlock(&dev->clientlist_mutex);
drm_dev_get(dev);
return 0;
......@@ -109,13 +106,33 @@ int drm_client_new(struct drm_device *dev, struct drm_client_dev *client,
return ret;
}
EXPORT_SYMBOL(drm_client_new);
EXPORT_SYMBOL(drm_client_init);
/**
* drm_client_add - Add client to the device list
* @client: DRM client
*
* Add the client to the &drm_device client list to activate its callbacks.
* @client must be initialized by a call to drm_client_init(). After
* drm_client_add() it is no longer permissible to call drm_client_release()
* directly (outside the unregister callback), instead cleanup will happen
* automatically on driver unload.
*/
void drm_client_add(struct drm_client_dev *client)
{
struct drm_device *dev = client->dev;
mutex_lock(&dev->clientlist_mutex);
list_add(&client->list, &dev->clientlist);
mutex_unlock(&dev->clientlist_mutex);
}
EXPORT_SYMBOL(drm_client_add);
/**
* drm_client_release - Release DRM client resources
* @client: DRM client
*
* Releases resources by closing the &drm_file that was opened by drm_client_new().
* Releases resources by closing the &drm_file that was opened by drm_client_init().
* It is called automatically if the &drm_client_funcs.unregister callback is _not_ set.
*
* This function should only be called from the unregister callback. An exception
......
......@@ -160,7 +160,7 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
fb_helper = &fbdev_cma->fb_helper;
ret = drm_client_new(dev, &fb_helper->client, "fbdev", NULL);
ret = drm_client_init(dev, &fb_helper->client, "fbdev", NULL);
if (ret)
goto err_free;
......@@ -169,6 +169,8 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
if (ret)
goto err_client_put;
drm_client_add(&fb_helper->client);
return fbdev_cma;
err_client_put:
......
......@@ -3218,12 +3218,14 @@ int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
if (!fb_helper)
return -ENOMEM;
ret = drm_client_new(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
if (ret) {
kfree(fb_helper);
return ret;
}
drm_client_add(&fb_helper->client);
fb_helper->preferred_bpp = preferred_bpp;
drm_fbdev_client_hotplug(&fb_helper->client);
......
......@@ -566,14 +566,14 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
lessee_priv->is_master = 1;
lessee_priv->authenticated = 1;
/* Hook up the fd */
fd_install(fd, lessee_file);
/* Pass fd back to userspace */
DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id);
cl->fd = fd;
cl->lessee_id = lessee->lessee_id;
/* Hook up the fd */
fd_install(fd, lessee_file);
DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
return 0;
......
......@@ -87,9 +87,10 @@ struct drm_client_dev {
struct drm_file *file;
};
int drm_client_new(struct drm_device *dev, struct drm_client_dev *client,
const char *name, const struct drm_client_funcs *funcs);
int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
const char *name, const struct drm_client_funcs *funcs);
void drm_client_release(struct drm_client_dev *client);
void drm_client_add(struct drm_client_dev *client);
void drm_client_dev_unregister(struct drm_device *dev);
void drm_client_dev_hotplug(struct drm_device *dev);
......
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