[kernel] r14474 - in dists/lenny-security/linux-2.6/debian: . patches/bugfix/all patches/series

Dann Frazier dannf at alioth.debian.org
Wed Oct 28 04:23:10 UTC 2009


Author: dannf
Date: Wed Oct 28 04:23:09 2009
New Revision: 14474

Log:
drm/r128: Add test for initialisation to all ioctls that require it
(CVE-2009-3620)

Added:
   dists/lenny-security/linux-2.6/debian/patches/bugfix/all/drm+r128-Add-test-for-init-to-all-reqd-ioctls.patch
Modified:
   dists/lenny-security/linux-2.6/debian/changelog
   dists/lenny-security/linux-2.6/debian/patches/series/19lenny2

Modified: dists/lenny-security/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny-security/linux-2.6/debian/changelog	Wed Oct 28 03:58:27 2009	(r14473)
+++ dists/lenny-security/linux-2.6/debian/changelog	Wed Oct 28 04:23:09 2009	(r14474)
@@ -3,6 +3,8 @@
   * tc: Fix uninitialized kernel memory leak (CVE-2009-3228)
   * random: make get_random_int() more random (CVE-2009-3238)
   * netlink: fix typo in initialization (CVE-2009-3612)
+  * drm/r128: Add test for initialisation to all ioctls that require it
+    (CVE-2009-3620)
 
  -- dann frazier <dannf at debian.org>  Tue, 27 Oct 2009 21:33:02 -0600
 

Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/drm+r128-Add-test-for-init-to-all-reqd-ioctls.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/drm+r128-Add-test-for-init-to-all-reqd-ioctls.patch	Wed Oct 28 04:23:09 2009	(r14474)
@@ -0,0 +1,222 @@
+commit 7dc482dfeeeefcfd000d4271c4626937406756d7
+Author: Ben Hutchings <ben at decadent.org.uk>
+Date:   Sun Aug 23 16:59:04 2009 +0100
+
+    drm/r128: Add test for initialisation to all ioctls that require it
+    
+    Almost all r128's private ioctls require that the CCE state has
+    already been initialised.  However, most do not test that this has
+    been done, and will proceed to dereference a null pointer.  This may
+    result in a security vulnerability, since some ioctls are
+    unprivileged.
+    
+    This adds a macro for the common initialisation test and changes all
+    ioctl implementations that require prior initialisation to use that
+    macro.
+    
+    Also, r128_do_init_cce() does not test that the CCE state has not
+    been initialised already.  Repeated initialisation may lead to a crash
+    or resource leak.  This adds that test.
+    
+    Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+    Signed-off-by: Dave Airlie <airlied at redhat.com>
+
+Backported to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/drivers/char/drm/r128_cce.c linux-source-2.6.26/drivers/char/drm/r128_cce.c
+--- linux-source-2.6.26.orig/drivers/char/drm/r128_cce.c	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/drivers/char/drm/r128_cce.c	2009-10-27 21:54:39.000000000 -0600
+@@ -353,6 +353,11 @@ static int r128_do_init_cce(struct drm_d
+ 
+ 	DRM_DEBUG("\n");
+ 
++	if (dev->dev_private) {
++		DRM_DEBUG("called when already initialized\n");
++		return -EINVAL;
++	}
++
+ 	dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
+ 	if (dev_priv == NULL)
+ 		return -ENOMEM;
+@@ -651,6 +656,8 @@ int r128_cce_start(struct drm_device *de
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
+ 		DRM_DEBUG("while CCE running\n");
+ 		return 0;
+@@ -673,6 +680,8 @@ int r128_cce_stop(struct drm_device *dev
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	/* Flush any pending CCE commands.  This ensures any outstanding
+ 	 * commands are exectuted by the engine before we turn it off.
+ 	 */
+@@ -710,10 +719,7 @@ int r128_cce_reset(struct drm_device *de
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
+-	if (!dev_priv) {
+-		DRM_DEBUG("called before init done\n");
+-		return -EINVAL;
+-	}
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+ 
+ 	r128_do_cce_reset(dev_priv);
+ 
+@@ -730,6 +736,8 @@ int r128_cce_idle(struct drm_device *dev
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	if (dev_priv->cce_running) {
+ 		r128_do_cce_flush(dev_priv);
+ 	}
+@@ -743,6 +751,8 @@ int r128_engine_reset(struct drm_device 
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev->dev_private);
++
+ 	return r128_do_engine_reset(dev);
+ }
+ 
+diff -urpN linux-source-2.6.26.orig/drivers/char/drm/r128_drv.h linux-source-2.6.26/drivers/char/drm/r128_drv.h
+--- linux-source-2.6.26.orig/drivers/char/drm/r128_drv.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/drivers/char/drm/r128_drv.h	2009-10-27 21:53:33.000000000 -0600
+@@ -418,6 +418,14 @@ static __inline__ void r128_update_ring_
+  * Misc helper macros
+  */
+ 
++#define DEV_INIT_TEST_WITH_RETURN(_dev_priv)				\
++do {									\
++	if (!_dev_priv) {						\
++		DRM_ERROR("called with no initialization\n");		\
++		return -EINVAL;						\
++	}								\
++} while (0)
++
+ #define RING_SPACE_TEST_WITH_RETURN( dev_priv )				\
+ do {									\
+ 	drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i;		\
+diff -urpN linux-source-2.6.26.orig/drivers/char/drm/r128_state.c linux-source-2.6.26/drivers/char/drm/r128_state.c
+--- linux-source-2.6.26.orig/drivers/char/drm/r128_state.c	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/drivers/char/drm/r128_state.c	2009-10-27 21:53:37.000000000 -0600
+@@ -1244,14 +1244,18 @@ static void r128_cce_dispatch_stipple(st
+ static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
+ {
+ 	drm_r128_private_t *dev_priv = dev->dev_private;
+-	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
++	drm_r128_sarea_t *sarea_priv;
+ 	drm_r128_clear_t *clear = data;
+ 	DRM_DEBUG("\n");
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
++	sarea_priv = dev_priv->sarea_priv;
++
+ 	if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
+ 		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+ 
+@@ -1312,6 +1316,8 @@ static int r128_cce_flip(struct drm_devi
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	if (!dev_priv->page_flipping)
+@@ -1331,6 +1337,8 @@ static int r128_cce_swap(struct drm_devi
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
+@@ -1354,10 +1362,7 @@ static int r128_cce_vertex(struct drm_de
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
+-	if (!dev_priv) {
+-		DRM_ERROR("called with no initialization\n");
+-		return -EINVAL;
+-	}
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+ 
+ 	DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
+ 		  DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
+@@ -1410,10 +1415,7 @@ static int r128_cce_indices(struct drm_d
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
+-	if (!dev_priv) {
+-		DRM_ERROR("called with no initialization\n");
+-		return -EINVAL;
+-	}
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+ 
+ 	DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
+ 		  elts->idx, elts->start, elts->end, elts->discard);
+@@ -1476,6 +1478,8 @@ static int r128_cce_blit(struct drm_devi
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx);
+ 
+ 	if (blit->idx < 0 || blit->idx >= dma->buf_count) {
+@@ -1501,6 +1505,8 @@ static int r128_cce_depth(struct drm_dev
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
+ 
+ 	ret = -EINVAL;
+@@ -1531,6 +1537,8 @@ static int r128_cce_stipple(struct drm_d
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+ 	if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
+ 		return -EFAULT;
+ 
+@@ -1555,10 +1563,7 @@ static int r128_cce_indirect(struct drm_
+ 
+ 	LOCK_TEST_WITH_RETURN(dev, file_priv);
+ 
+-	if (!dev_priv) {
+-		DRM_ERROR("called with no initialization\n");
+-		return -EINVAL;
+-	}
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+ 
+ 	DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
+ 		  indirect->idx, indirect->start, indirect->end,
+@@ -1620,10 +1625,7 @@ static int r128_getparam(struct drm_devi
+ 	drm_r128_getparam_t *param = data;
+ 	int value;
+ 
+-	if (!dev_priv) {
+-		DRM_ERROR("called with no initialization\n");
+-		return -EINVAL;
+-	}
++	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+ 
+ 	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
+ 

Modified: dists/lenny-security/linux-2.6/debian/patches/series/19lenny2
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/series/19lenny2	Wed Oct 28 03:58:27 2009	(r14473)
+++ dists/lenny-security/linux-2.6/debian/patches/series/19lenny2	Wed Oct 28 04:23:09 2009	(r14474)
@@ -1,3 +1,4 @@
 + bugfix/all/tc-fix-pad-leak.patch
 + bugfix/all/random-make-get_random_int-more-random.patch
 + bugfix/all/netlink-fix-typo-in-initialization.patch
++ bugfix/all/drm+r128-Add-test-for-init-to-all-reqd-ioctls.patch



More information about the Kernel-svn-changes mailing list