Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Nov 2013 11:15:52 +0000 (UTC)
From:      Jean-Sebastien Pedron <dumbbell@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r258549 - head/sys/dev/drm2
Message-ID:  <201311251115.rAPBFqoJ007134@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dumbbell
Date: Mon Nov 25 11:15:51 2013
New Revision: 258549
URL: http://svnweb.freebsd.org/changeset/base/258549

Log:
  drm: Dereference pointers given to qsort_r()'s cmp callback
  
  drm_le_cmp() (qsort_r()'s callback) receives pointers to elements in the
  array passed to qsort_r(), not the elements themselves.
  
  Before this fix, the use of qsort_r() shuffled the array, not sorted it,
  because the compare callback accessed random memory locations, not the
  expected elements.
  
  This bug triggered an infinite loop in KDE/xserver:
  
      1. KDE has a kded module called "randrmonitor" which queries xserver
         for current monitors at startup and then listens to RandR
         notifications from xserver.
  
      2. xserver handles the query from "randrmonitor" by polling the
         video device using the "drm_mode_getconnector()" ioctl. This
         ioctl returns a list of connectors and, for those with a
         connected monitor, the available modes. Each modes list is sorted
         by the kernel before returning. When xserver gets the connectors
         list, it sorts the modes lists again.
  
         In the case of this bug, when two modes are equal (in xserver's
         compare function PoV), their order is kept stable (ie. the
         kernel order is kept for those two modes). And because the list
         was shuffled by the kernel, the order of two equal modes was
         frequently changed in the final modes list in xserver.
  
      3. xserver compares the returned connectors list with the list
         obtained earlier. In particular, it compares the sorted
         modes lists for each connector. If a property of a connector
         changes (eg. modes), xserver sends a "RRNotify_OutputChange"
         notification.
  
         Because of the change of order between equal modes, xserver sent
         a notification after each polling of the connectors.
  
      4. "randrmonitor" receives a notification, triggered by its query. The
         notification doesn't contain the new connectors list, therefore, it
         asks for the new list using the same function: go back to step #2.
  
  MFC after:	3 days

Modified:
  head/sys/dev/drm2/drm_linux_list_sort.c

Modified: head/sys/dev/drm2/drm_linux_list_sort.c
==============================================================================
--- head/sys/dev/drm2/drm_linux_list_sort.c	Mon Nov 25 11:02:58 2013	(r258548)
+++ head/sys/dev/drm2/drm_linux_list_sort.c	Mon Nov 25 11:15:51 2013	(r258549)
@@ -42,8 +42,8 @@ drm_le_cmp(void *priv, const void *d1, c
 	struct drm_list_sort_thunk *thunk;
 
 	thunk = priv;
-	le1 = __DECONST(struct list_head *, d1);
-	le2 = __DECONST(struct list_head *, d2);
+	le1 = *(struct list_head **)d1;
+	le2 = *(struct list_head **)d2;
 	return ((thunk->cmp)(thunk->priv, le1, le2));
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311251115.rAPBFqoJ007134>