[PATCH v2 03/10] xfree86: duplicate xorg.conf device information before xf86NewInputDevice

Peter Hutterer peter.hutterer at who-t.net
Thu Jul 7 23:19:01 PDT 2011


xf86ConfigLayout.inputs contains the information from the xorg.conf
file. Passing this into xf86NewInputDevice means the device will get
cleaned up on exit and the pointers in xf86ConfigLayout.inputs are left
dangling. In the second server generation, this results in a server
crash.

Also, rename pDev to pInfo. pDev is pretty much reserved for DeviceIntPtr
types.

Reproducible: AutoAddDevices off and xorg.conf input sections, trigger
server regeneration.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Changes to v1:
- copy type_name too, otherwise drivers that don't set the type_name in
  PreInit cause a segfault on strdup(NULL)

 hw/xfree86/common/xf86Init.c |   31 ++++++++++++++++++++++++++-----
 1 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 15fdbc3..51059fc 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -791,6 +791,20 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
 				 NULL);
 }
 
+static InputInfoPtr
+duplicateDevice(InputInfoPtr pInfo)
+{
+    InputInfoPtr dup = calloc(1, sizeof(InputInfoRec));
+    if (dup) {
+        dup->name = strdup(pInfo->name);
+        dup->driver = strdup(pInfo->driver);
+        dup->options = xf86OptionListDuplicate(pInfo->options);
+        /* type_name is a const string */
+        dup->type_name = pInfo->type_name;
+    }
+    return dup;
+}
+
 /*
  * InitInput --
  *      Initialize all supported input devices.
@@ -799,7 +813,7 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
 void
 InitInput(int argc, char **argv)
 {
-    InputInfoPtr* pDev;
+    InputInfoPtr* pInfo;
     DeviceIntPtr dev;
 
     xf86Info.vtRequestsPending = FALSE;
@@ -807,14 +821,21 @@ InitInput(int argc, char **argv)
     mieqInit();
 
     /* Initialize all configured input devices */
-    for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
+    for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
+        InputInfoPtr dup;
         /* Replace obsolete keyboard driver with kbd */
-        if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
-            strcpy((*pDev)->driver, "kbd");
+        if (!xf86NameCmp((*pInfo)->driver, "keyboard")) {
+            strcpy((*pInfo)->driver, "kbd");
         }
 
+        /* Data passed into xf86NewInputDevice will be freed on shutdown.
+         * Duplicate from xf86ConfigLayout.inputs, otherwise we don't have any
+         * xorg.conf input devices in the second generation
+         */
+        dup = duplicateDevice(*pInfo);
+
         /* If one fails, the others will too */
-        if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
+        if (xf86NewInputDevice(dup, &dev, TRUE) == BadAlloc)
             break;
     }
 
-- 
1.7.5.4



More information about the xorg-devel mailing list