From patchwork Wed Oct 11 00:48:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Packard X-Patchwork-Id: 9998237 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B7D8060230 for ; Wed, 11 Oct 2017 00:48:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9C662872C for ; Wed, 11 Oct 2017 00:48:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9EB2828814; Wed, 11 Oct 2017 00:48:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1BCCC2872C for ; Wed, 11 Oct 2017 00:48:52 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BC58B6E5CC; Wed, 11 Oct 2017 00:48:39 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from elaine.keithp.com (home.keithp.com [63.227.221.253]) by gabe.freedesktop.org (Postfix) with ESMTP id C7D246E5CA for ; Wed, 11 Oct 2017 00:48:37 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by elaine.keithp.com (Postfix) with ESMTP id ABADB3F210E2; Tue, 10 Oct 2017 17:48:37 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at keithp.com Received: from elaine.keithp.com ([127.0.0.1]) by localhost (elaine.keithp.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 3XjvLUUZuV1a; Tue, 10 Oct 2017 17:48:34 -0700 (PDT) Received: from vr.keithp.com (vr.keithp.com [10.0.0.39]) by elaine.keithp.com (Postfix) with ESMTP id EBDE13F20E4D; Tue, 10 Oct 2017 17:48:33 -0700 (PDT) Received: by vr.keithp.com (Postfix, from userid 1000) id BD215740072; Tue, 10 Oct 2017 17:48:33 -0700 (PDT) From: Keith Packard To: linux-kernel@vger.kernel.org, Dave Airlie , Daniel Vetter Subject: [PATCH 5/6] drm: Check mode object lease status in all master ioctl paths [v2] Date: Tue, 10 Oct 2017 17:48:30 -0700 Message-Id: <20171011004831.9624-6-keithp@keithp.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20171011004831.9624-1-keithp@keithp.com> References: <20171011004831.9624-1-keithp@keithp.com> Cc: Keith Packard , dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 | 5 +++-- drivers/gpu/drm/drm_encoder.c | 8 +++++--- drivers/gpu/drm/drm_mode_config.c | 32 +++++++++++++++++++------------- drivers/gpu/drm/drm_mode_object.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/drm_plane.c | 8 +++++--- drivers/gpu/drm/drm_vblank.c | 18 ++++++++++++++++-- 7 files changed, 71 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 541177c71d51..bab26b477738 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -310,7 +310,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 704fc8934616..0712c14cb57c 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1315,7 +1315,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, return -ENOENT; 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_encoders >= encoders_count) && encoders_count) { @@ -1382,7 +1383,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; diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index 43f644844b83..6ad6416f2ede 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -226,7 +226,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; @@ -234,8 +234,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 74f6ff5df656..fad6646b38d3 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -122,20 +122,24 @@ int drm_mode_getresources(struct drm_device *dev, void *data, count = 0; crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr); drm_for_each_crtc(crtc, dev) { - if (count < card_res->count_crtcs && - put_user(crtc->base.id, crtc_id + count)) - return -EFAULT; - count++; + if (drm_lease_held(file_priv, crtc->base.id)) { + if (count < card_res->count_crtcs && + put_user(crtc->base.id, crtc_id + count)) + return -EFAULT; + count++; + } } card_res->count_crtcs = count; count = 0; encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr); drm_for_each_encoder(encoder, dev) { - if (count < card_res->count_encoders && - put_user(encoder->base.id, encoder_id + count)) - return -EFAULT; - count++; + if (drm_lease_held(file_priv, encoder->base.id)) { + if (count < card_res->count_encoders && + put_user(encoder->base.id, encoder_id + count)) + return -EFAULT; + count++; + } } card_res->count_encoders = count; @@ -143,12 +147,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data, count = 0; connector_id = u64_to_user_ptr(card_res->connector_id_ptr); drm_for_each_connector_iter(connector, &conn_iter) { - if (count < card_res->count_connectors && - put_user(connector->base.id, connector_id + count)) { - drm_connector_list_iter_end(&conn_iter); - return -EFAULT; + if (drm_lease_held(file_priv, connector->base.id)) { + if (count < card_res->count_connectors && + put_user(connector->base.id, connector_id + count)) { + drm_connector_list_iter_end(&conn_iter); + return -EFAULT; + } + count++; } - count++; } card_res->count_connectors = count; drm_connector_list_iter_end(&conn_iter); diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 240a05d91a53..ef8befe34bdf 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -104,6 +104,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) @@ -117,6 +136,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 574fd1475214..e0bb14ad0312 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -518,9 +518,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data, return -ENOENT; drm_modeset_lock(&plane->mutex, NULL); - if (plane->state && plane->state->crtc) + if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id)) plane_resp->crtc_id = plane->state->crtc->base.id; - else if (!plane->state && plane->crtc) + else if (!plane->state && 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; @@ -534,7 +534,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; /* diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 45ac2efd5078..583a17a212a9 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1459,10 +1459,12 @@ static u64 widen_32_to_64(u32 narrow, u64 near) int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_crtc *crtc; struct drm_vblank_crtc *vblank; union drm_wait_vblank *vblwait = data; int ret; u64 req_seq; + unsigned int pipe_index; unsigned int flags, seq, pipe, high_pipe; if (!dev->irq_enabled) @@ -1484,9 +1486,21 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); if (high_pipe) - pipe = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT; + pipe_index = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT; else - pipe = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; + pipe_index = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; + + /* Convert lease-relative crtc index into global crtc index */ + pipe = 0; + drm_for_each_crtc(crtc, dev) { + if (drm_lease_held(file_priv, crtc->base.id)) { + if (pipe_index == 0) + break; + pipe_index--; + } + pipe++; + } + if (pipe >= dev->num_crtcs) return -EINVAL;