[PATCH libinput 5/9] evdev: remove a race condition opening the wrong device
Hans de Goede
hdegoede at redhat.com
Mon Nov 24 01:00:01 PST 2014
Hi,
On 11/24/2014 01:46 AM, Peter Hutterer wrote:
> Potential race condition:
> - udev notifies us that a udev_device became available
> - we go for a coffee and chat to the neighbours on the way
> - the device is unplugged
> - a new device is plugged in, gets the same devnode
> - we finish our coffee and come back
> - open(udev_device_get_devnode())
> - new device is now opened as the old device
>
> To avoid the above race, we compare the syspath of the device at the open fd
> with the syspath of the device we originally wanted. If they differ, we fail.
>
> evdev_compare_syspath was simply moved up.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Looks good:
Reviewed-by: Hans de Goede <hdegoede at redhat.com>
Regards,
Hans
> ---
> src/evdev.c | 49 ++++++++++++++++++++++++++-----------------------
> 1 file changed, 26 insertions(+), 23 deletions(-)
>
> diff --git a/src/evdev.c b/src/evdev.c
> index 8d457f2..8897cd4 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1449,6 +1449,29 @@ evdev_notify_added_device(struct evdev_device *device)
> notify_added_device(&device->base);
> }
>
> +static int
> +evdev_device_compare_syspath(struct udev_device *udev_device, int fd)
> +{
> + struct udev *udev = udev_device_get_udev(udev_device);
> + struct udev_device *udev_device_new;
> + struct stat st;
> + int rc = 1;
> +
> + if (fstat(fd, &st) < 0)
> + goto out;
> +
> + udev_device_new = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
> + if (!udev_device_new)
> + goto out;
> +
> + rc = strcmp(udev_device_get_syspath(udev_device_new),
> + udev_device_get_syspath(udev_device));
> +out:
> + if (udev_device_new)
> + udev_device_unref(udev_device_new);
> + return rc;
> +}
> +
> struct evdev_device *
> evdev_device_create(struct libinput_seat *seat,
> struct udev_device *udev_device)
> @@ -1471,6 +1494,9 @@ evdev_device_create(struct libinput_seat *seat,
> return NULL;
> }
>
> + if (evdev_device_compare_syspath(udev_device, fd) != 0)
> + goto err;
> +
> device = zalloc(sizeof *device);
> if (device == NULL)
> goto err;
> @@ -1909,29 +1935,6 @@ evdev_device_suspend(struct evdev_device *device)
> return 0;
> }
>
> -static int
> -evdev_device_compare_syspath(struct udev_device *udev_device, int fd)
> -{
> - struct udev *udev = udev_device_get_udev(udev_device);
> - struct udev_device *udev_device_new;
> - struct stat st;
> - int rc = 1;
> -
> - if (fstat(fd, &st) < 0)
> - goto out;
> -
> - udev_device_new = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
> - if (!udev_device_new)
> - goto out;
> -
> - rc = strcmp(udev_device_get_syspath(udev_device_new),
> - udev_device_get_syspath(udev_device));
> -out:
> - if (udev_device_new)
> - udev_device_unref(udev_device_new);
> - return rc;
> -}
> -
> int
> evdev_device_resume(struct evdev_device *device)
> {
>
More information about the wayland-devel
mailing list