From patchwork Fri Aug 23 11:13:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 2848722 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 182B39F239 for ; Fri, 23 Aug 2013 11:17:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 56254202EA for ; Fri, 23 Aug 2013 11:17:15 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 64EC7201F2 for ; Fri, 23 Aug 2013 11:17:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3A672E8164 for ; Fri, 23 Aug 2013 04:17:12 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ea0-f182.google.com (mail-ea0-f182.google.com [209.85.215.182]) by gabe.freedesktop.org (Postfix) with ESMTP id 3D4F1E8161 for ; Fri, 23 Aug 2013 04:13:52 -0700 (PDT) Received: by mail-ea0-f182.google.com with SMTP id o10so237063eaj.27 for ; Fri, 23 Aug 2013 04:13:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=p7PKhtwbKbYCt7ChfPojeYuSuoNcSc5Telkpa2sT5fs=; b=w2b3OxyZiFDx1igpaKYruh5sbng3GqV/fTxY5okvZccT6bgc7eAWmEc5aZ2NMSwBLP SU59VJg39029VrSRznHkFRT8m7wFlJ4xhTMTC1E3hh9nvIKdHQr+MM/7bDI4mPgFzjdl hhYQtUeRR99kX8YsdDXuplSnilCXfnLNhXq/KRrhcmG+e84nHO9Itf0CMiwvAsVMb0yU 92iUuodwRyxZkciKAZ02L8d9yh/vwjTOt/27eww/9tr5UMOCteF5ZyZJX+YE1TyvuGrj ZeapfTuKiPeY80XBQJAN3520ZKOFgmP3OEepD9t7yNy+hobaV9OvO40M7gstM7x9dbnX TyGg== X-Received: by 10.14.176.8 with SMTP id a8mr25920917eem.12.1377256431621; Fri, 23 Aug 2013 04:13:51 -0700 (PDT) Received: from localhost.localdomain (stgt-5f71ad45.pool.mediaWays.net. [95.113.173.69]) by mx.google.com with ESMTPSA id h52sm24059543eez.3.1969.12.31.16.00.00 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 23 Aug 2013 04:13:50 -0700 (PDT) From: David Herrmann To: dri-devel@lists.freedesktop.org Subject: [PATCH v2 2/6] drm/gem: implement vma access management Date: Fri, 23 Aug 2013 13:13:24 +0200 Message-Id: <1377256408-746-3-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1377256408-746-1-git-send-email-dh.herrmann@gmail.com> References: <1377256408-746-1-git-send-email-dh.herrmann@gmail.com> Cc: Dave Airlie X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We implement automatic vma mmap() access management for all drivers using gem_mmap. We use the vma manager to add each open-file that creates a gem-handle to the vma-node of the underlying gem object. Once the handle is destroyed, we drop the open-file again. This allows us to use drm_vma_node_is_allowed() on _any_ gem object to see whether an open-file is granted access. In drm_gem_mmap() we use this to verify that unprivileged users cannot guess gem offsets and map arbitrary buffers. Note that this manages access for _all_ gem users (also TTM+GEM), but the actual access checks are only done for drm_gem_mmap(). TTM drivers use the TTM mmap helpers, which need to do that separately. Signed-off-by: David Herrmann --- drivers/gpu/drm/drm_gem.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index d6122ae..b2d59b2 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -298,6 +298,7 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) spin_unlock(&filp->table_lock); drm_gem_remove_prime_handles(obj, filp); + drm_vma_node_revoke(&obj->vma_node, filp->filp); if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, filp); @@ -357,6 +358,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, } *handlep = ret; + ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp); + if (ret) { + drm_gem_handle_delete(file_priv, *handlep); + return ret; + } if (dev->driver->gem_open_object) { ret = dev->driver->gem_open_object(obj, file_priv); @@ -701,6 +707,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) struct drm_device *dev = obj->dev; drm_gem_remove_prime_handles(obj, file_priv); + drm_vma_node_revoke(&obj->vma_node, file_priv->filp); if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); @@ -793,6 +800,10 @@ EXPORT_SYMBOL(drm_gem_vm_close); * the GEM object is not looked up based on its fake offset. To implement the * DRM mmap operation, drivers should use the drm_gem_mmap() function. * + * drm_gem_mmap_obj() assumes the user is granted access to the buffer while + * drm_gem_mmap() prevents unprivileged users from mapping random objects. So + * callers must verify access restrictions before calling this helper. + * * NOTE: This function has to be protected with dev->struct_mutex * * Return 0 or success or -EINVAL if the object size is smaller than the VMA @@ -841,6 +852,9 @@ EXPORT_SYMBOL(drm_gem_mmap_obj); * Look up the GEM object based on the offset passed in (vma->vm_pgoff will * contain the fake offset we created when the GTT map ioctl was called on * the object) and map it with a call to drm_gem_mmap_obj(). + * + * If the caller is not granted access to the buffer object, the mmap will fail + * with EACCES. Please see the vma manager for more information. */ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) { @@ -861,6 +875,9 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) if (!node) { mutex_unlock(&dev->struct_mutex); return drm_mmap(filp, vma); + } else if (!drm_vma_node_is_allowed(node, filp)) { + mutex_unlock(&dev->struct_mutex); + return -EACCES; } obj = container_of(node, struct drm_gem_object, vma_node);