[PATCH xf86-input-libinput] Fix crash when using threaded input and the first device goes away

Hans de Goede hdegoede at redhat.com
Wed Oct 5 13:33:45 UTC 2016


Hi,

On 05-10-16 15:31, Hans de Goede wrote:
> When the xserver uses threaded input, it keeps a pointer to the InputInfo
> passed into xf86AddEnabledDevice and calls pointer->read_input on events.
>
> But when the first enabled device goes away the pInfo we've passed into
> xf86AddEnabledDevice gets freed and eventually pInfo->read_input gets
> overwritten (or pInfo points to unmapped memory) leading to a segfault.
>
> This commit fixes this by replacing the pInfo passed into
> xf86AddEnabledDevice with a pointer to a global InputInfo stored inside
> the driver_context struct.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Forgot to add a buglink, this fixes:

https://bugzilla.redhat.com/show_bug.cgi?id=1381840

Regards,

Hans


> ---
>  src/xf86libinput.c | 22 ++++++++++++++++------
>  1 file changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/src/xf86libinput.c b/src/xf86libinput.c
> index 21f87f5..485e212 100644
> --- a/src/xf86libinput.c
> +++ b/src/xf86libinput.c
> @@ -86,6 +86,7 @@
>
>  struct xf86libinput_driver {
>  	struct libinput *libinput;
> +	struct _InputInfoRec InputInfo;
>  	int device_enabled_count;
>  };
>
> @@ -582,7 +583,17 @@ xf86libinput_on(DeviceIntPtr dev)
>
>  	if (driver_context.device_enabled_count == 0) {
>  #if HAVE_THREADED_INPUT
> -		xf86AddEnabledDevice(pInfo);
> +		/*
> +		 * The xserver keeps a pointer to the InputInfo passed into
> +		 * xf86AddEnabledDevice and calls pointer->read_input on
> +		 * events. Thus we cannot simply pass in our current pInfo
> +		 * as that will be deleted when the current input device gets
> +		 * unplugged. Instead pass in a pointer to a global
> +		 * InputInfo inside the driver_context.
> +		 */
> +		driver_context.InputInfo.fd = pInfo->fd;
> +		driver_context.InputInfo.read_input = pInfo->read_input;
> +		xf86AddEnabledDevice(&driver_context.InputInfo);
>  #else
>  		/* Can't use xf86AddEnabledDevice on an epollfd */
>  		AddEnabledDevice(pInfo->fd);
> @@ -606,7 +617,7 @@ xf86libinput_off(DeviceIntPtr dev)
>
>  	if (--driver_context.device_enabled_count == 0) {
>  #if HAVE_THREADED_INPUT
> -		xf86RemoveEnabledDevice(pInfo);
> +		xf86RemoveEnabledDevice(&driver_context.InputInfo);
>  #else
>  		RemoveEnabledDevice(pInfo->fd);
>  #endif
> @@ -1923,7 +1934,7 @@ out:
>  }
>
>  static void
> -xf86libinput_read_input(InputInfoPtr pInfo)
> +xf86libinput_read_input(InputInfoPtr do_not_use)
>  {
>  	struct libinput *libinput = driver_context.libinput;
>  	int rc;
> @@ -1934,9 +1945,8 @@ xf86libinput_read_input(InputInfoPtr pInfo)
>  		return;
>
>  	if (rc < 0) {
> -		xf86IDrvMsg(pInfo, X_ERROR,
> -			    "Error reading events: %s\n",
> -			    strerror(-rc));
> +		xf86Msg(X_ERROR, "Error reading libinput events: %s\n",
> +			strerror(-rc));
>  		return;
>  	}
>
>


More information about the xorg-devel mailing list