All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Herrmann <dh.herrmann@gmail.com>
To: dri-devel@lists.freedesktop.org
Subject: [PATCH 10/16] drm/gem: implement mmap access management
Date: Tue, 13 Aug 2013 21:38:31 +0200	[thread overview]
Message-ID: <1376422717-12229-11-git-send-email-dh.herrmann@gmail.com> (raw)
In-Reply-To: <1376422717-12229-1-git-send-email-dh.herrmann@gmail.com>

Implement automatic access management for mmap offsets for all GEM
drivers. This prevents user-space applications from "guessing" GEM BO
offsets and accessing buffers which they don't own.

TTM drivers or other modesetting drivers with custom mm handling might
make use of GEM but don't need its mmap helpers. To avoid unnecessary
overhead, we limit GEM access management to drivers using DRIVER_GEM_MMAP.
So for TTM drivers GEM will not call any *_allow() or *_revoke() helpers.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 Documentation/DocBook/drm.tmpl | 13 +++++++++++++
 drivers/gpu/drm/drm_gem.c      | 36 ++++++++++++++++++++++++++++++++----
 include/drm/drmP.h             |  1 +
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 87e22ec..a388749 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -223,6 +223,19 @@
             </para></listitem>
           </varlistentry>
           <varlistentry>
+            <term>DRIVER_GEM_MMAP</term>
+            <listitem><para>
+              Driver uses default GEM mmap helpers. This flag guarantees that
+              GEM core takes care of buffer access management and prevents
+              unprivileged users from mapping random buffers. This flag should
+              only be set by GEM-only drivers that use the drm_gem_mmap_*()
+              helpers directly. TTM, on the other hand, takes care of access
+              management itself, even though drivers might use DRIVER_GEM and
+              TTM at the same time. See the DRM VMA Offset Manager interface for
+              more information on buffer mmap() access management.
+            </para></listitem>
+          </varlistentry>
+          <varlistentry>
             <term>DRIVER_MODESET</term>
             <listitem><para>
               Driver supports mode setting interfaces (KMS).
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 7043d89..887274f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -236,6 +236,9 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
 
 	drm_gem_remove_prime_handles(obj, filp);
 
+	if (drm_core_check_feature(dev, DRIVER_GEM_MMAP))
+		drm_vma_node_revoke(&obj->vma_node, filp->filp);
+
 	if (dev->driver->gem_close_object)
 		dev->driver->gem_close_object(obj, filp);
 	drm_gem_object_handle_unreference_unlocked(obj);
@@ -288,15 +291,26 @@ drm_gem_handle_create(struct drm_file *file_priv,
 
 	drm_gem_object_handle_reference(obj);
 
+	if (drm_core_check_feature(dev, DRIVER_GEM_MMAP)) {
+		ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp);
+		if (ret)
+			goto err_handle;
+	}
+
 	if (dev->driver->gem_open_object) {
 		ret = dev->driver->gem_open_object(obj, file_priv);
-		if (ret) {
-			drm_gem_handle_delete(file_priv, *handlep);
-			return ret;
-		}
+		if (ret)
+			goto err_node;
 	}
 
 	return 0;
+
+err_node:
+	if (drm_core_check_feature(dev, DRIVER_GEM_MMAP))
+		drm_vma_node_revoke(&obj->vma_node, file_priv->filp);
+err_handle:
+	drm_gem_handle_delete(file_priv, *handlep);
+	return ret;
 }
 EXPORT_SYMBOL(drm_gem_handle_create);
 
@@ -486,6 +500,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
 
 	drm_gem_remove_prime_handles(obj, file_priv);
 
+	if (drm_core_check_feature(dev, DRIVER_GEM_MMAP))
+		drm_vma_node_revoke(&obj->vma_node, file_priv->filp);
+
 	if (dev->driver->gem_close_object)
 		dev->driver->gem_close_object(obj, file_priv);
 
@@ -610,6 +627,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
@@ -658,6 +679,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 DRIVER_GEM_MMAP for more information.
  */
 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 {
@@ -678,6 +702,10 @@ 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_core_check_feature(dev, DRIVER_GEM_MMAP) &&
+		   !drm_vma_node_is_allowed(node, filp)) {
+		mutex_unlock(&dev->struct_mutex);
+		return -EACCES;
 	}
 
 	obj = container_of(node, struct drm_gem_object, vma_node);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3ecdde6..d51accd 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -152,6 +152,7 @@ int drm_err(const char *func, const char *format, ...);
 #define DRIVER_GEM         0x1000
 #define DRIVER_MODESET     0x2000
 #define DRIVER_PRIME       0x4000
+#define DRIVER_GEM_MMAP    0x8000
 
 #define DRIVER_BUS_PCI 0x1
 #define DRIVER_BUS_PLATFORM 0x2
-- 
1.8.3.4

  parent reply	other threads:[~2013-08-13 19:40 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-13 19:38 [PATCH 00/16] DRM VMA Access Management David Herrmann
2013-08-13 19:38 ` [PATCH 01/16] drm/vma: add access management helpers David Herrmann
2013-08-13 19:38 ` [PATCH 02/16] drm/ast: implement mmap access managament David Herrmann
2013-08-13 19:38 ` [PATCH 03/16] drm/cirrus: " David Herrmann
2013-08-13 19:38 ` [PATCH 04/16] drm/mgag200: " David Herrmann
2013-08-13 19:38 ` [PATCH 05/16] drm/nouveau: " David Herrmann
2013-08-13 19:38 ` [PATCH 06/16] drm/radeon: " David Herrmann
2013-08-13 19:38 ` [PATCH 07/16] drm/qxl: " David Herrmann
2013-08-13 19:38 ` [PATCH 08/16] drm/vmwgfx: " David Herrmann
2013-08-13 21:44   ` David Herrmann
2013-08-14 17:35     ` Thomas Hellstrom
2013-08-16 13:19       ` David Herrmann
2013-08-16 15:33         ` Thomas Hellstrom
2013-08-16 17:01           ` David Herrmann
2013-08-16 17:27             ` Thomas Hellstrom
2013-08-13 19:38 ` [PATCH 09/16] drm/ttm: prevent mmap access to unauthorized users David Herrmann
2013-08-13 19:38 ` David Herrmann [this message]
2013-08-13 21:05   ` [PATCH 10/16] drm/gem: implement mmap access management Daniel Vetter
2013-08-23 11:14     ` David Herrmann
2013-08-13 19:38 ` [PATCH 11/16] drm/i915: enable GEM " David Herrmann
2013-08-13 19:38 ` [PATCH 12/16] drm/exynos: " David Herrmann
2013-08-13 19:38 ` [PATCH 13/16] drm/gma500: " David Herrmann
2013-08-13 19:38 ` [PATCH 14/16] drm/omap: " David Herrmann
2013-08-13 19:46   ` Rob Clark
2013-08-13 19:38 ` [PATCH 15/16] drm/udl: " David Herrmann
2013-08-13 19:38 ` [PATCH 16/16] drm/host1x: " David Herrmann

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=1376422717-12229-11-git-send-email-dh.herrmann@gmail.com \
    --to=dh.herrmann@gmail.com \
    --cc=dri-devel@lists.freedesktop.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.