From: Keith Packard <keithp@keithp.com>
To: linux-kernel@vger.kernel.org, Dave Airlie <airlied@redhat.com>,
Daniel Vetter <daniel@ffwll.ch>
Cc: Keith Packard <keithp@keithp.com>, dri-devel@lists.freedesktop.org
Subject: [PATCH 4/5] drm: Check mode object lease status in all master ioctl paths [v2]
Date: Fri, 28 Apr 2017 23:07:01 -0700 [thread overview]
Message-ID: <20170429060702.6656-5-keithp@keithp.com> (raw)
In-Reply-To: <20170429060702.6656-1-keithp@keithp.com>
Attempts to modify un-leased objects are rejected with an error.
Information returned about unleased objects is modified to make them
appear unusable and/or disconnected.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
With the change in the __drm_mode_object_find API to pass the
file_priv along, we can now centralize most of the lease-based access
checks in that function.
A few places skip that API and require in-line checks.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_auth.c | 2 +-
drivers/gpu/drm/drm_connector.c | 8 +++---
drivers/gpu/drm/drm_encoder.c | 8 +++---
drivers/gpu/drm/drm_mode_config.c | 52 ++++++++++++++++++++++++---------------
drivers/gpu/drm/drm_mode_object.c | 22 +++++++++++++++++
drivers/gpu/drm/drm_plane.c | 6 +++--
6 files changed, 69 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 1db4f63860d1..44c99d12f4c1 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -303,7 +303,7 @@ void drm_master_release(struct drm_file *file_priv)
*/
bool drm_is_current_master(struct drm_file *fpriv)
{
- return fpriv->is_master && fpriv->master == fpriv->minor->dev->master;
+ return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
}
EXPORT_SYMBOL(drm_is_current_master);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 670c20d5660c..dbf34f08363b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1094,7 +1094,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
}
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
- if (connector->encoder_ids[i] != 0)
+ if (connector->encoder_ids[i] != 0 &&
+ drm_lease_held(file_priv, connector->encoder_ids[i]))
encoders_count++;
if (out_resp->count_modes == 0) {
@@ -1118,7 +1119,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
encoder = drm_connector_get_encoder(connector);
- if (encoder)
+ if (encoder && drm_lease_held(file_priv, encoder->base.id))
out_resp->encoder_id = encoder->base.id;
else
out_resp->encoder_id = 0;
@@ -1156,7 +1157,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
copied = 0;
encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
- if (connector->encoder_ids[i] != 0) {
+ if (connector->encoder_ids[i] != 0 &&
+ drm_lease_held(file_priv, connector->encoder_ids[i])) {
if (put_user(connector->encoder_ids[i],
encoder_ptr + copied)) {
ret = -EFAULT;
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index dbaedd4e12e6..512d0b6cb7d2 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -211,7 +211,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
crtc = drm_encoder_get_crtc(encoder);
- if (crtc)
+ if (crtc && drm_lease_held(file_priv, crtc->base.id))
enc_resp->crtc_id = crtc->base.id;
else
enc_resp->crtc_id = 0;
@@ -219,8 +219,10 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
enc_resp->encoder_type = encoder->encoder_type;
enc_resp->encoder_id = encoder->base.id;
- enc_resp->possible_crtcs = encoder->possible_crtcs;
- enc_resp->possible_clones = encoder->possible_clones;
+ enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ encoder->possible_crtcs);
+ enc_resp->possible_clones = drm_lease_filter_encoders(file_priv,
+ encoder->possible_clones);
return 0;
}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 2735a5847ffa..bb6b64e594b7 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -131,14 +131,20 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
/* mode_config.mutex protects the connector list against e.g. DP MST
* connector hot-adding. CRTC/Plane lists are invariant. */
mutex_lock(&dev->mode_config.mutex);
- drm_for_each_crtc(crtc, dev)
- crtc_count++;
+ drm_for_each_crtc(crtc, dev) {
+ if (drm_lease_held(file_priv, crtc->base.id))
+ crtc_count++;
+ }
- drm_for_each_connector(connector, dev)
- connector_count++;
+ drm_for_each_connector(connector, dev) {
+ if (drm_lease_held(file_priv, connector->base.id))
+ connector_count++;
+ }
- drm_for_each_encoder(encoder, dev)
- encoder_count++;
+ drm_for_each_encoder(encoder, dev) {
+ if (drm_lease_held(file_priv, encoder->base.id))
+ encoder_count++;
+ }
card_res->max_height = dev->mode_config.max_height;
card_res->min_height = dev->mode_config.min_height;
@@ -150,11 +156,13 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
copied = 0;
crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
drm_for_each_crtc(crtc, dev) {
- if (put_user(crtc->base.id, crtc_id + copied)) {
- ret = -EFAULT;
- goto out;
+ if (drm_lease_held(file_priv, crtc->base.id)) {
+ if (put_user(crtc->base.id, crtc_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
}
- copied++;
}
}
card_res->count_crtcs = crtc_count;
@@ -164,12 +172,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
copied = 0;
encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
drm_for_each_encoder(encoder, dev) {
- if (put_user(encoder->base.id, encoder_id +
- copied)) {
- ret = -EFAULT;
- goto out;
+ if (drm_lease_held(file_priv, encoder->base.id)) {
+ if (put_user(encoder->base.id, encoder_id +
+ copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
}
- copied++;
}
}
card_res->count_encoders = encoder_count;
@@ -179,12 +189,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
copied = 0;
connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
drm_for_each_connector(connector, dev) {
- if (put_user(connector->base.id,
- connector_id + copied)) {
- ret = -EFAULT;
- goto out;
+ if (drm_lease_held(file_priv, connector->base.id)) {
+ if (put_user(connector->base.id,
+ connector_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
}
- copied++;
}
}
card_res->count_connectors = connector_count;
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index daddc7640139..9763787492cc 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -107,6 +107,25 @@ void drm_mode_object_unregister(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex);
}
+/**
+ * drm_lease_required - check types which must be leased to be used
+ * @type: type of object
+ *
+ * Returns whether the provided type of drm_mode_object must
+ * be owned or leased to be used by a process.
+ */
+static bool drm_lease_required(uint32_t type)
+{
+ switch(type) {
+ case DRM_MODE_OBJECT_CRTC:
+ case DRM_MODE_OBJECT_CONNECTOR:
+ case DRM_MODE_OBJECT_ENCODER:
+ return true;
+ default:
+ return false;
+ }
+}
+
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
struct drm_file *file_priv,
uint32_t id, uint32_t type)
@@ -120,6 +139,9 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
if (obj && obj->id != id)
obj = NULL;
+ if (obj && drm_lease_required(obj->type) && !_drm_lease_held(file_priv, obj->id))
+ obj = NULL;
+
if (obj && obj->free_cb) {
if (!kref_get_unless_zero(&obj->refcount))
obj = NULL;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 819f74616f34..c9c687cdc747 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -392,7 +392,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
return -ENOENT;
drm_modeset_lock(&plane->mutex, NULL);
- if (plane->crtc)
+ if (plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
plane_resp->crtc_id = plane->crtc->base.id;
else
plane_resp->crtc_id = 0;
@@ -404,7 +404,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
drm_modeset_unlock(&plane->mutex);
plane_resp->plane_id = plane->base.id;
- plane_resp->possible_crtcs = plane->possible_crtcs;
+ plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ plane->possible_crtcs);
+
plane_resp->gamma_size = 0;
/*
--
2.11.0
next prev parent reply other threads:[~2017-04-29 6:07 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-01 17:08 [PATCH 0/4] drm: Add mode resource leasing Keith Packard
2017-04-01 17:08 ` [PATCH 1/4] drm: Add new LEASE debug level Keith Packard
2017-04-01 17:08 ` [PATCH 2/4] drm: Add drm_object lease infrastructure Keith Packard
2017-04-02 13:38 ` Daniel Vetter
2017-04-02 16:31 ` Keith Packard
2017-04-10 5:16 ` Michel Dänzer
2017-04-02 17:51 ` Daniel Vetter
2017-04-02 19:59 ` Keith Packard
2017-04-01 17:08 ` [PATCH 3/4] drm: Check mode object lease status in all master ioctl paths Keith Packard
2017-04-02 13:19 ` Daniel Vetter
2017-04-02 16:37 ` Keith Packard
2017-04-03 7:49 ` Daniel Vetter
2017-04-10 1:06 ` Keith Packard
2017-04-01 17:08 ` [PATCH 4/4] drm: Add four ioctls for managing drm mode object leases Keith Packard
2017-04-02 13:23 ` Daniel Vetter
2017-04-02 16:44 ` Keith Packard
2017-04-29 6:06 ` [PATCH 0/5] drm: Add mode resource leasing [v2] Keith Packard
2017-04-29 6:06 ` [PATCH 1/5] drm: Pass struct drm_file * to __drm_mode_object_find Keith Packard
2017-04-29 6:06 ` [PATCH 2/5] drm: Add new LEASE debug level Keith Packard
2017-04-29 6:07 ` [PATCH 3/5] drm: Add drm_object lease infrastructure [v2] Keith Packard
2017-04-29 6:07 ` Keith Packard [this message]
2017-04-29 6:07 ` [PATCH 5/5] drm: Add three ioctls for managing drm mode object leases [v2] Keith Packard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170429060702.6656-5-keithp@keithp.com \
--to=keithp@keithp.com \
--cc=airlied@redhat.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox