- fb_helper: Fix NULL deref in legacy drivers (Noralf)
- leases: Ensure lessees can't connect to objects outside their perview (Daniel) - leases: Enforce that lessees hold the lease for implicitly set planes (Daniel) - leases: A few non-functional cleanups (Daniel) Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Noralf Trønnes <noralf@tronnes.org> -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEfxcpfMSgdnQMs+QqlvcN/ahKBwoFAlzAxJ0ACgkQlvcN/ahK BwrfwggAheZ3GKONVBmhjkWkLNh00a0nbw0M7iFkJkvCtTEJTqUi+ZtAKhJHM/oh LwvzalBLTVtYtsmwm9PGCRPS5gHKK2/Nv7+sWpUlieQyyaGvBIFwqx0RuH1wQKO+ +igT81sJbnIFvO4nkX4sSg3S52EFHd7CLalxA8QORhZ6QyvJ2Eay1YdeBYpR8wXc lI4FMGei8KhckP80U8BO/NwCGYLa9y0H+fsCrSqy1b5FJ8qmvJYU7sGNoGFHS3Nq HoWG6uaCc9jVHVElw9UD9bvE4R/TQg5g8/irBhcElCVQ0cxqGORRcSMLxGGrcrRi 1VF2W9kTF4TgCwDb5Q9pp6+RgLujkg== =rSSS -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-fixes-2019-04-24' of git://anongit.freedesktop.org/drm/drm-misc into drm-next - fb_helper: Fix NULL deref in legacy drivers (Noralf) - leases: Ensure lessees can't connect to objects outside their perview (Daniel) - leases: Enforce that lessees hold the lease for implicitly set planes (Daniel) - leases: A few non-functional cleanups (Daniel) Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Noralf Trønnes <noralf@tronnes.org> Signed-off-by: Dave Airlie <airlied@redhat.com> From: Sean Paul <sean@poorly.run> Link: https://patchwork.freedesktop.org/patch/msgid/20190424210604.GA32581@art_vandelay
This commit is contained in:
commit
5a67928651
|
@ -512,8 +512,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drm_atomic_plane_set_property(struct drm_plane *plane,
|
static int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||||
struct drm_plane_state *state, struct drm_property *property,
|
struct drm_plane_state *state, struct drm_file *file_priv,
|
||||||
uint64_t val)
|
struct drm_property *property, uint64_t val)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = plane->dev;
|
struct drm_device *dev = plane->dev;
|
||||||
struct drm_mode_config *config = &dev->mode_config;
|
struct drm_mode_config *config = &dev->mode_config;
|
||||||
|
@ -521,7 +521,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (property == config->prop_fb_id) {
|
if (property == config->prop_fb_id) {
|
||||||
struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
|
struct drm_framebuffer *fb;
|
||||||
|
fb = drm_framebuffer_lookup(dev, file_priv, val);
|
||||||
drm_atomic_set_fb_for_plane(state, fb);
|
drm_atomic_set_fb_for_plane(state, fb);
|
||||||
if (fb)
|
if (fb)
|
||||||
drm_framebuffer_put(fb);
|
drm_framebuffer_put(fb);
|
||||||
|
@ -537,7 +538,9 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
} else if (property == config->prop_crtc_id) {
|
} else if (property == config->prop_crtc_id) {
|
||||||
struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
|
struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val);
|
||||||
|
if (val && !crtc)
|
||||||
|
return -EACCES;
|
||||||
return drm_atomic_set_crtc_for_plane(state, crtc);
|
return drm_atomic_set_crtc_for_plane(state, crtc);
|
||||||
} else if (property == config->prop_crtc_x) {
|
} else if (property == config->prop_crtc_x) {
|
||||||
state->crtc_x = U642I64(val);
|
state->crtc_x = U642I64(val);
|
||||||
|
@ -668,14 +671,16 @@ static int drm_atomic_set_writeback_fb_for_connector(
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drm_atomic_connector_set_property(struct drm_connector *connector,
|
static int drm_atomic_connector_set_property(struct drm_connector *connector,
|
||||||
struct drm_connector_state *state, struct drm_property *property,
|
struct drm_connector_state *state, struct drm_file *file_priv,
|
||||||
uint64_t val)
|
struct drm_property *property, uint64_t val)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
struct drm_mode_config *config = &dev->mode_config;
|
struct drm_mode_config *config = &dev->mode_config;
|
||||||
|
|
||||||
if (property == config->prop_crtc_id) {
|
if (property == config->prop_crtc_id) {
|
||||||
struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
|
struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val);
|
||||||
|
if (val && !crtc)
|
||||||
|
return -EACCES;
|
||||||
return drm_atomic_set_crtc_for_connector(state, crtc);
|
return drm_atomic_set_crtc_for_connector(state, crtc);
|
||||||
} else if (property == config->dpms_property) {
|
} else if (property == config->dpms_property) {
|
||||||
/* setting DPMS property requires special handling, which
|
/* setting DPMS property requires special handling, which
|
||||||
|
@ -736,8 +741,10 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
|
||||||
} else if (property == connector->colorspace_property) {
|
} else if (property == connector->colorspace_property) {
|
||||||
state->colorspace = val;
|
state->colorspace = val;
|
||||||
} else if (property == config->writeback_fb_id_property) {
|
} else if (property == config->writeback_fb_id_property) {
|
||||||
struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
|
struct drm_framebuffer *fb;
|
||||||
int ret = drm_atomic_set_writeback_fb_for_connector(state, fb);
|
int ret;
|
||||||
|
fb = drm_framebuffer_lookup(dev, file_priv, val);
|
||||||
|
ret = drm_atomic_set_writeback_fb_for_connector(state, fb);
|
||||||
if (fb)
|
if (fb)
|
||||||
drm_framebuffer_put(fb);
|
drm_framebuffer_put(fb);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -934,6 +941,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
int drm_atomic_set_property(struct drm_atomic_state *state,
|
int drm_atomic_set_property(struct drm_atomic_state *state,
|
||||||
|
struct drm_file *file_priv,
|
||||||
struct drm_mode_object *obj,
|
struct drm_mode_object *obj,
|
||||||
struct drm_property *prop,
|
struct drm_property *prop,
|
||||||
uint64_t prop_value)
|
uint64_t prop_value)
|
||||||
|
@ -956,7 +964,8 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_atomic_connector_set_property(connector,
|
ret = drm_atomic_connector_set_property(connector,
|
||||||
connector_state, prop, prop_value);
|
connector_state, file_priv,
|
||||||
|
prop, prop_value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DRM_MODE_OBJECT_CRTC: {
|
case DRM_MODE_OBJECT_CRTC: {
|
||||||
|
@ -984,7 +993,8 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_atomic_plane_set_property(plane,
|
ret = drm_atomic_plane_set_property(plane,
|
||||||
plane_state, prop, prop_value);
|
plane_state, file_priv,
|
||||||
|
prop, prop_value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -1354,8 +1364,8 @@ retry:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_atomic_set_property(state, obj, prop,
|
ret = drm_atomic_set_property(state, file_priv,
|
||||||
prop_value);
|
obj, prop, prop_value);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
drm_mode_object_put(obj);
|
drm_mode_object_put(obj);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -108,8 +108,6 @@ struct drm_master *drm_master_create(struct drm_device *dev)
|
||||||
master->dev = dev;
|
master->dev = dev;
|
||||||
|
|
||||||
/* initialize the tree of output resource lessees */
|
/* initialize the tree of output resource lessees */
|
||||||
master->lessor = NULL;
|
|
||||||
master->lessee_id = 0;
|
|
||||||
INIT_LIST_HEAD(&master->lessees);
|
INIT_LIST_HEAD(&master->lessees);
|
||||||
INIT_LIST_HEAD(&master->lessee_list);
|
INIT_LIST_HEAD(&master->lessee_list);
|
||||||
idr_init(&master->leases);
|
idr_init(&master->leases);
|
||||||
|
|
|
@ -559,6 +559,10 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
||||||
|
|
||||||
plane = crtc->primary;
|
plane = crtc->primary;
|
||||||
|
|
||||||
|
/* allow disabling with the primary plane leased */
|
||||||
|
if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
mutex_lock(&crtc->dev->mode_config.mutex);
|
mutex_lock(&crtc->dev->mode_config.mutex);
|
||||||
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
|
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
|
||||||
DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
|
DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
|
||||||
|
|
|
@ -214,6 +214,7 @@ int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
|
||||||
struct drm_connector *connector,
|
struct drm_connector *connector,
|
||||||
int mode);
|
int mode);
|
||||||
int drm_atomic_set_property(struct drm_atomic_state *state,
|
int drm_atomic_set_property(struct drm_atomic_state *state,
|
||||||
|
struct drm_file *file_priv,
|
||||||
struct drm_mode_object *obj,
|
struct drm_mode_object *obj,
|
||||||
struct drm_property *prop,
|
struct drm_property *prop,
|
||||||
uint64_t prop_value);
|
uint64_t prop_value);
|
||||||
|
|
|
@ -2588,6 +2588,9 @@ static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper,
|
||||||
int num_connectors_detected = 0;
|
int num_connectors_detected = 0;
|
||||||
struct drm_modeset_acquire_ctx ctx;
|
struct drm_modeset_acquire_ctx ctx;
|
||||||
|
|
||||||
|
if (!drm_drv_uses_atomic_modeset(dev))
|
||||||
|
return false;
|
||||||
|
|
||||||
save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
|
save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
|
||||||
if (!save_enabled)
|
if (!save_enabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -111,7 +111,7 @@ static bool _drm_has_leased(struct drm_master *master, int id)
|
||||||
*/
|
*/
|
||||||
bool _drm_lease_held(struct drm_file *file_priv, int id)
|
bool _drm_lease_held(struct drm_file *file_priv, int id)
|
||||||
{
|
{
|
||||||
if (file_priv == NULL || file_priv->master == NULL)
|
if (!file_priv || !file_priv->master)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return _drm_lease_held_master(file_priv->master, id);
|
return _drm_lease_held_master(file_priv->master, id);
|
||||||
|
@ -133,7 +133,7 @@ bool drm_lease_held(struct drm_file *file_priv, int id)
|
||||||
struct drm_master *master;
|
struct drm_master *master;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
if (file_priv == NULL || file_priv->master == NULL)
|
if (!file_priv || !file_priv->master || !file_priv->master->lessor)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
master = file_priv->master;
|
master = file_priv->master;
|
||||||
|
@ -159,7 +159,7 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
|
||||||
int count_in, count_out;
|
int count_in, count_out;
|
||||||
uint32_t crtcs_out = 0;
|
uint32_t crtcs_out = 0;
|
||||||
|
|
||||||
if (file_priv == NULL || file_priv->master == NULL)
|
if (!file_priv || !file_priv->master || !file_priv->master->lessor)
|
||||||
return crtcs_in;
|
return crtcs_in;
|
||||||
|
|
||||||
master = file_priv->master;
|
master = file_priv->master;
|
||||||
|
@ -220,8 +220,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
|
||||||
error = 0;
|
error = 0;
|
||||||
if (!idr_find(&dev->mode_config.object_idr, object))
|
if (!idr_find(&dev->mode_config.object_idr, object))
|
||||||
error = -ENOENT;
|
error = -ENOENT;
|
||||||
else if (!_drm_lease_held_master(lessor, object))
|
|
||||||
error = -EACCES;
|
|
||||||
else if (_drm_has_leased(lessor, object))
|
else if (_drm_has_leased(lessor, object))
|
||||||
error = -EBUSY;
|
error = -EBUSY;
|
||||||
|
|
||||||
|
@ -403,11 +401,6 @@ static int fill_object_idr(struct drm_device *dev,
|
||||||
/* step one - get references to all the mode objects
|
/* step one - get references to all the mode objects
|
||||||
and check for validity. */
|
and check for validity. */
|
||||||
for (o = 0; o < object_count; o++) {
|
for (o = 0; o < object_count; o++) {
|
||||||
if ((int) object_ids[o] < 0) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out_free_objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
objects[o] = drm_mode_object_find(dev, lessor_priv,
|
objects[o] = drm_mode_object_find(dev, lessor_priv,
|
||||||
object_ids[o],
|
object_ids[o],
|
||||||
DRM_MODE_OBJECT_ANY);
|
DRM_MODE_OBJECT_ANY);
|
||||||
|
|
|
@ -451,6 +451,7 @@ static int set_property_legacy(struct drm_mode_object *obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_property_atomic(struct drm_mode_object *obj,
|
static int set_property_atomic(struct drm_mode_object *obj,
|
||||||
|
struct drm_file *file_priv,
|
||||||
struct drm_property *prop,
|
struct drm_property *prop,
|
||||||
uint64_t prop_value)
|
uint64_t prop_value)
|
||||||
{
|
{
|
||||||
|
@ -477,7 +478,7 @@ retry:
|
||||||
obj_to_connector(obj),
|
obj_to_connector(obj),
|
||||||
prop_value);
|
prop_value);
|
||||||
} else {
|
} else {
|
||||||
ret = drm_atomic_set_property(state, obj, prop, prop_value);
|
ret = drm_atomic_set_property(state, file_priv, obj, prop, prop_value);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
ret = drm_atomic_commit(state);
|
ret = drm_atomic_commit(state);
|
||||||
|
@ -520,7 +521,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
|
||||||
goto out_unref;
|
goto out_unref;
|
||||||
|
|
||||||
if (drm_drv_uses_atomic_modeset(property->dev))
|
if (drm_drv_uses_atomic_modeset(property->dev))
|
||||||
ret = set_property_atomic(arg_obj, property, arg->value);
|
ret = set_property_atomic(arg_obj, file_priv, property, arg->value);
|
||||||
else
|
else
|
||||||
ret = set_property_legacy(arg_obj, property, arg->value);
|
ret = set_property_legacy(arg_obj, property, arg->value);
|
||||||
|
|
||||||
|
|
|
@ -960,6 +960,11 @@ retry:
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (!drm_lease_held(file_priv, crtc->cursor->base.id)) {
|
||||||
|
ret = -EACCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx);
|
ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1062,6 +1067,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
||||||
|
|
||||||
plane = crtc->primary;
|
plane = crtc->primary;
|
||||||
|
|
||||||
|
if (!drm_lease_held(file_priv, plane->base.id))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
if (crtc->funcs->page_flip_target) {
|
if (crtc->funcs->page_flip_target) {
|
||||||
u32 current_vblank;
|
u32 current_vblank;
|
||||||
int r;
|
int r;
|
||||||
|
|
Loading…
Reference in New Issue