e_input: prevent memory corruption in libinput_device APIs 55/300455/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Tue, 24 Oct 2023 09:54:57 +0000 (18:54 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 25 Oct 2023 08:01:17 +0000 (17:01 +0900)
Change-Id: I9dfc1de9620673ff99fde354fbcc595118f1f670
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/bin/e_input.c
src/bin/e_input.h
src/bin/e_input_evdev.c
src/bin/e_input_inputs.c

index 23690fe..21d9e24 100644 (file)
@@ -159,6 +159,7 @@ e_input_init(Ecore_Evas *ee)
      }
 
    // TODO : make this variable configurable e.g. e.cfg
+   g_rec_mutex_init(&e_input->libinput_mutex);
    e_input->input_base_dir = eina_stringshare_add("/dev/input");
    e_input->use_thread = EINA_FALSE;
 
@@ -293,6 +294,8 @@ e_input_shutdown(void)
    if (e_input->input_base_dir)
      eina_stringshare_del(e_input->input_base_dir);
    e_input_device_close(e_input->dev);
+
+   g_rec_mutex_clear(&e_input->libinput_mutex);
    free(e_input);
 
    ecore_event_evas_shutdown();
index f623a3a..915f847 100644 (file)
@@ -73,6 +73,8 @@ struct _E_Input
 
    e_input_relative_motion_cb relative_motion_handler;
    e_input_keyboard_grab_key_cb keyboard_grab_key_handler;
+
+   GRecMutex libinput_mutex;
 };
 
 struct _E_Input_Device
index 0cca759..ffccc23 100644 (file)
@@ -2302,6 +2302,8 @@ _e_input_evdev_device_create(E_Input_Seat *seat, struct libinput_device *device)
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
 
+   E_Input *e_input = e_input_get();
+
    /* try to allocate space for new evdev */
    if (!(edev = calloc(1, sizeof(E_Input_Evdev)))) return NULL;
 
@@ -2312,6 +2314,9 @@ _e_input_evdev_device_create(E_Input_Seat *seat, struct libinput_device *device)
    g_rec_mutex_init(&edev->touch.raw_pressed_mutex);
    g_rec_mutex_init(&edev->touch.blocked_mutex);
 
+   if (e_input)
+     g_rec_mutex_lock(&e_input->libinput_mutex);
+
    if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD))
      {
         edev->caps |= E_INPUT_SEAT_KEYBOARD;
@@ -2368,6 +2373,9 @@ _e_input_evdev_device_create(E_Input_Seat *seat, struct libinput_device *device)
    /* configure device */
    _device_configure(edev);
 
+   if (e_input)
+     g_rec_mutex_unlock(&e_input->libinput_mutex);
+
    return edev;
 }
 
@@ -2375,6 +2383,7 @@ void
 _e_input_evdev_device_destroy(E_Input_Evdev *edev)
 {
    Ecore_Device *dev;
+   E_Input *e_input = e_input_get();
 
    EINA_SAFETY_ON_NULL_RETURN(edev);
 
@@ -2412,7 +2421,9 @@ _e_input_evdev_device_destroy(E_Input_Evdev *edev)
           }
      }
    if (edev->path) eina_stringshare_del(edev->path);
+   if (e_input) g_rec_mutex_lock(&e_input->libinput_mutex);
    if (edev->device) libinput_device_unref(edev->device);
+   if (e_input) g_rec_mutex_unlock(&e_input->libinput_mutex);
    if (edev->key_remap_hash) eina_hash_free(edev->key_remap_hash);
    if (edev->touch.coords)
      {
@@ -2700,6 +2711,7 @@ e_input_evdev_seatname_set(E_Input_Evdev *evdev, const char *seatname)
 {
    Eina_Bool res = EINA_FALSE;
    E_Input_Backend *input;
+   E_Input *e_input = e_input_get();
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(seatname, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(evdev, EINA_FALSE);
@@ -2709,12 +2721,23 @@ e_input_evdev_seatname_set(E_Input_Evdev *evdev, const char *seatname)
      {
         input = evdev->seat->input;
         if (!input) return EINA_FALSE;
+
+        if (e_input)
+          g_rec_mutex_lock(&e_input->libinput_mutex);
+
         if (libinput_dispatch(input->libinput) != 0)
           {
              ERR("Failed to dispatch libinput events: %m");
+
+             if (e_input)
+               g_rec_mutex_unlock(&e_input->libinput_mutex);
+
              return EINA_FALSE;
           }
 
+        if (e_input)
+          g_rec_mutex_unlock(&e_input->libinput_mutex);
+
         /* process pending events */
         _input_events_process(input);
         res = EINA_TRUE;
index c9df039..8e1243d 100644 (file)
@@ -537,12 +537,19 @@ void
 _input_events_process(E_Input_Backend *input)
 {
    struct libinput_event *event;
+   E_Input *e_input = e_input_get();
+
+   if (e_input)
+     g_rec_mutex_lock(&e_input->libinput_mutex);
 
    while ((event = libinput_get_event(input->libinput)))
      {
         _input_event_process(event);
         libinput_event_destroy(event);
      }
+
+   if (e_input)
+     g_rec_mutex_unlock(&e_input->libinput_mutex);
 }
 
 static Eina_Bool
@@ -581,6 +588,8 @@ input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
    if (!src) return G_SOURCE_REMOVE;
    if (!input) return G_SOURCE_REMOVE;
 
+   E_Input *e_input = e_input_get();
+
    GIOCondition cond;
    cond = g_source_query_unix_fd(source, src->tag);
 
@@ -593,9 +602,15 @@ input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
    if (!input->libinput)
      return G_SOURCE_REMOVE;
 
+   if (e_input)
+     g_rec_mutex_lock(&e_input->libinput_mutex);
+
    if (libinput_dispatch(input->libinput) != 0)
      ERR("Failed to dispatch libinput events: %m");
 
+   if (e_input)
+     g_rec_mutex_unlock(&e_input->libinput_mutex);
+
    /* process pending events */
    _input_events_process(input);