[PATCH 3/3] xf86: guarantee compat_output in the range [ -1 .. num_output-1 ]

vdb at picaros.org vdb at picaros.org
Thu Jul 18 04:40:55 PDT 2013


The current code allows for compat_output >= num_output when
num_output decreases to zero.  Thus hw/xfree86/modes/xf86Crtc.h
xf86CompatOutput() may read beyond the end of the output array via
config->output[config->compat_output].

Move the compat_output update into its own if() block.  Then it is
always updated to the last selected compat output, including
the compat == -1 case.

Signed-off-by: Servaas Vandenberghe
---
 hw/xfree86/modes/xf86Crtc.c |   35 ++++++++++++++++++++---------------
 1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 1d15a46..bf4b204 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1831,22 +1831,27 @@ SetCompatOutput(xf86CrtcConfigPtr config)
         }
     }
 
-    if (compat >= 0) {
-        if (compat != config->compat_output) {
-            config->compat_output = compat;
-            /* Set screen scrn->monitor info. */
-            xf86SetDDCproperties(output->scrn, output->MonInfo);
-        }
-    }
-    else if (config->compat_output >= 0 && config->compat_output < config->num_output) {
-        /* Don't change the compat output when no valid outputs found */
-        output = config->output[config->compat_output];
+    if (!output) {
+        /* All outputs are disconnected from crtc or monitor */
+        if (config->compat_output >= 0 
+	    && config->compat_output < config->num_output) {
+            /* Don't change the compat output when no valid outputs found */
+	    compat = config->compat_output;
+	    output = config->output[compat];
+	}
+	else if (config->num_output > 0) {
+	    /* All outputs are disconnected, select one to fake */
+	    compat = 0;
+	    output = config->output[compat];
+	}
     }
-    else if (config->num_output > 0) {
-        /* All outputs are disconnected, select one to fake */
-        config->compat_output = 0;
-        output = config->output[config->compat_output];
-        xf86SetDDCproperties(output->scrn, output->MonInfo);
+
+    if (compat != config->compat_output) {
+        /* compat range [ -1 .. num_output-1 ] */
+        config->compat_output = compat;
+        /* Set screen scrn->monitor info. */
+        if (output)
+	    xf86SetDDCproperties(output->scrn, output->MonInfo);
     }
 
     return output;
-- 
1.7.4.5



More information about the xorg-devel mailing list