dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Hellstrom <thellstrom@vmware.com>
To: dri-devel@lists.freedesktop.org
Cc: pv-drivers@vmware.com, Thomas Hellstrom <thellstrom@vmware.com>,
	linux-graphics-maintainer@vmware.com
Subject: [PATCH 09/16] drm/vmwgfx: Reinstate and tighten security around legacy master model
Date: Tue, 25 Mar 2014 14:19:01 +0100	[thread overview]
Message-ID: <1395753548-17441-10-git-send-email-thellstrom@vmware.com> (raw)
In-Reply-To: <1395753548-17441-1-git-send-email-thellstrom@vmware.com>

The following restrictions affect clients connecting using legacy nodes:

*) Masters that have dropped master privilieges are not considered
   authenticated until they regain master privileges.
*) Clients whose master have dropped master privileges block interruptibly on
   ioctls  requiring authentication until their master regains master
   privileges. If their master exits, they are killed.

This is primarily designed to prevent clients authenticated with one master to
access data from clients authenticated with another master.
(Think fast user-switching or data sniffers enabled while X is vt-switched).

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |   94 +++++++++++++++++++++++++++++++++--
 1 file changed, 89 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 54cfeb6..8fdbe26 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -982,12 +982,70 @@ out_no_tfile:
 	return ret;
 }
 
-static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
-			       unsigned long arg)
+static struct vmw_master *vmw_master_check(struct drm_device *dev,
+					   struct drm_file *file_priv,
+					   unsigned int flags)
+{
+	int ret;
+	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+	struct vmw_master *vmaster;
+
+	if (file_priv->minor->type != DRM_MINOR_LEGACY ||
+	    !(flags & DRM_AUTH))
+		return NULL;
+
+	ret = mutex_lock_interruptible(&dev->master_mutex);
+	if (unlikely(ret != 0))
+		return ERR_PTR(-ERESTARTSYS);
+
+	if (file_priv->is_master) {
+		mutex_unlock(&dev->master_mutex);
+		return NULL;
+	}
+
+	/*
+	 * Check if we were previously master, but now dropped.
+	 */
+	if (vmw_fp->locked_master) {
+		mutex_unlock(&dev->master_mutex);
+		DRM_ERROR("Dropped master trying to access ioctl that "
+			  "requires authentication.\n");
+		return ERR_PTR(-EACCES);
+	}
+	mutex_unlock(&dev->master_mutex);
+
+	/*
+	 * Taking the drm_global_mutex after the TTM lock might deadlock
+	 */
+	if (!(flags & DRM_UNLOCKED)) {
+		DRM_ERROR("Refusing locked ioctl access.\n");
+		return ERR_PTR(-EDEADLK);
+	}
+
+	/*
+	 * Take the TTM lock. Possibly sleep waiting for the authenticating
+	 * master to become master again, or for a SIGTERM if the
+	 * authenticating master exits.
+	 */
+	vmaster = vmw_master(file_priv->master);
+	ret = ttm_read_lock(&vmaster->lock, true);
+	if (unlikely(ret != 0))
+		vmaster = ERR_PTR(ret);
+
+	return vmaster;
+}
+
+static long vmw_generic_ioctl(struct file *filp, unsigned int cmd,
+			      unsigned long arg,
+			      long (*ioctl_func)(struct file *, unsigned int,
+						 unsigned long))
 {
 	struct drm_file *file_priv = filp->private_data;
 	struct drm_device *dev = file_priv->minor->dev;
 	unsigned int nr = DRM_IOCTL_NR(cmd);
+	struct vmw_master *vmaster;
+	unsigned int flags;
+	long ret;
 
 	/*
 	 * Do extra checking on driver private ioctls.
@@ -996,18 +1054,44 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
 	if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
 	    && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
 		const struct drm_ioctl_desc *ioctl =
-		    &vmw_ioctls[nr - DRM_COMMAND_BASE];
+			&vmw_ioctls[nr - DRM_COMMAND_BASE];
 
 		if (unlikely(ioctl->cmd_drv != cmd)) {
 			DRM_ERROR("Invalid command format, ioctl %d\n",
 				  nr - DRM_COMMAND_BASE);
 			return -EINVAL;
 		}
+		flags = ioctl->flags;
+	} else if (!drm_ioctl_flags(nr, &flags))
+		return -EINVAL;
+
+	vmaster = vmw_master_check(dev, file_priv, flags);
+	if (unlikely(IS_ERR(vmaster))) {
+		DRM_INFO("IOCTL ERROR %d\n", nr);
+		return PTR_ERR(vmaster);
 	}
 
-	return drm_ioctl(filp, cmd, arg);
+	ret = ioctl_func(filp, cmd, arg);
+	if (vmaster)
+		ttm_read_unlock(&vmaster->lock);
+
+	return ret;
+}
+
+static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
+			       unsigned long arg)
+{
+	return vmw_generic_ioctl(filp, cmd, arg, &drm_ioctl);
 }
 
+#ifdef CONFIG_COMPAT
+static long vmw_compat_ioctl(struct file *filp, unsigned int cmd,
+			     unsigned long arg)
+{
+	return vmw_generic_ioctl(filp, cmd, arg, &drm_compat_ioctl);
+}
+#endif
+
 static void vmw_lastclose(struct drm_device *dev)
 {
 	struct drm_crtc *crtc;
@@ -1315,7 +1399,7 @@ static const struct file_operations vmwgfx_driver_fops = {
 	.poll = vmw_fops_poll,
 	.read = vmw_fops_read,
 #if defined(CONFIG_COMPAT)
-	.compat_ioctl = drm_compat_ioctl,
+	.compat_ioctl = vmw_compat_ioctl,
 #endif
 	.llseek = noop_llseek,
 };
-- 
1.7.10.4

  parent reply	other threads:[~2014-03-25 13:19 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-25 13:18 [PATCH 00/16] vmwgfx render-node support Thomas Hellstrom
2014-03-25 13:18 ` [PATCH 01/16] drm: Have the crtc code only reference master from legacy nodes v2 Thomas Hellstrom
2014-03-25 13:18 ` [PATCH 02/16] drm: Break out ioctl permission check to a separate function v2 Thomas Hellstrom
2014-03-25 13:18 ` [PATCH 03/16] drm: Make control nodes master-less v3 Thomas Hellstrom
2014-03-26 18:55   ` David Herrmann
2014-03-25 13:18 ` [PATCH 04/16] drm: Improve on minor type helpers v2 Thomas Hellstrom
2014-03-26 18:54   ` David Herrmann
2014-03-25 13:18 ` [PATCH 05/16] drm: Remove the minor master list Thomas Hellstrom
2014-03-25 13:18 ` [PATCH 06/16] drm: Protect the master management with a drm_device::master_mutex Thomas Hellstrom
2014-03-26 19:08   ` David Herrmann
2014-03-26 20:40     ` Thomas Hellstrom
2014-03-26 22:38       ` Daniel Vetter
2014-03-27 23:44       ` David Herrmann
2014-03-25 13:18 ` [PATCH 07/16] drm: Add a function to get the ioctl flags Thomas Hellstrom
2014-03-25 13:19 ` [PATCH 08/16] drm/vmwgfx: Use a per-device semaphore for reservation protection Thomas Hellstrom
2014-03-25 13:19 ` Thomas Hellstrom [this message]
2014-03-25 13:19 ` [PATCH 10/16] drm/vmwgfx: Drop authentication requirement on UNREF ioctls Thomas Hellstrom
2014-03-25 13:19 ` [PATCH 11/16] drm/vmwgfx: Allow prime fds in the surface reference ioctls Thomas Hellstrom
2014-03-25 13:19 ` [PATCH 12/16] drm/vmwgfx: Tighten security around surface sharing Thomas Hellstrom
2014-03-25 13:19 ` [PATCH 13/16] drm/ttm: Add a ttm_ref_object_exists function Thomas Hellstrom
2014-03-25 13:19 ` [PATCH 14/16] drm/vmwgfx: Tighten the security around buffer maps Thomas Hellstrom
2014-03-25 13:19 ` [PATCH 15/16] drm/vmwgfx: Enable render nodes Thomas Hellstrom
2014-03-25 13:19 ` [PATCH 16/16] drm/vmwgfx: Bump driver minor and date Thomas Hellstrom

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=1395753548-17441-10-git-send-email-thellstrom@vmware.com \
    --to=thellstrom@vmware.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-graphics-maintainer@vmware.com \
    --cc=pv-drivers@vmware.com \
    /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