From 47aab6391f55f3251beaddf811de0e12263ad25d Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Tue, 24 Oct 2023 18:54:57 +0900 Subject: [PATCH] e_input: prevent memory corruption in libinput_device APIs Change-Id: I9dfc1de9620673ff99fde354fbcc595118f1f670 Signed-off-by: Jihoon Kim --- src/bin/e_input.c | 3 +++ src/bin/e_input.h | 2 ++ src/bin/e_input_evdev.c | 23 +++++++++++++++++++++++ src/bin/e_input_inputs.c | 15 +++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/bin/e_input.c b/src/bin/e_input.c index 23690fe..21d9e24 100644 --- a/src/bin/e_input.c +++ b/src/bin/e_input.c @@ -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(); diff --git a/src/bin/e_input.h b/src/bin/e_input.h index f623a3a..915f847 100644 --- a/src/bin/e_input.h +++ b/src/bin/e_input.h @@ -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 diff --git a/src/bin/e_input_evdev.c b/src/bin/e_input_evdev.c index 0cca759..ffccc23 100644 --- a/src/bin/e_input_evdev.c +++ b/src/bin/e_input_evdev.c @@ -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; diff --git a/src/bin/e_input_inputs.c b/src/bin/e_input_inputs.c index c9df039..8e1243d 100644 --- a/src/bin/e_input_inputs.c +++ b/src/bin/e_input_inputs.c @@ -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); -- 2.7.4