[PATCH 4/5] drm: Check mode object lease status in all master ioctl paths [v2]

2017-04-29 Thread Keith Packard
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 :

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 
---
 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(>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(>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(>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))
+   

[PATCH 4/5] drm: Check mode object lease status in all master ioctl paths [v2]

2017-04-29 Thread Keith Packard
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 :

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 
---
 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(>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(>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(>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++;
+   }
 
-