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

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to