summaryrefslogtreecommitdiff
path: root/src/lib/efl_wl
diff options
context:
space:
mode:
authorDerek Foreman <derek.foreman.samsung@gmail.com>2018-08-17 12:46:39 -0400
committerMike Blumenkrantz <zmike@samsung.com>2018-08-17 12:46:39 -0400
commit6fe7e1155db768dcafa9f24af8f6b98230974813 (patch)
tree9105e2f493021cac492f5859df3c7ab727f374af /src/lib/efl_wl
parent15cc9a65aa8656d4183b9eada790143363c7dc06 (diff)
efl_wl: Send unique keymap fds to clients
Summary: Prevent wayland clients from being able to destroy the compositor's singleton keymap by making individual copies for each client. Reviewers: zmike, devilhorns Reviewed By: devilhorns Subscribers: cedric, #reviewers, #committers, zmike Tags: #efl Differential Revision: https://phab.enlightenment.org/D6862
Diffstat (limited to 'src/lib/efl_wl')
-rw-r--r--src/lib/efl_wl/Efl_Wl.h5
-rw-r--r--src/lib/efl_wl/efl_wl.c110
2 files changed, 63 insertions, 52 deletions
diff --git a/src/lib/efl_wl/Efl_Wl.h b/src/lib/efl_wl/Efl_Wl.h
index 9124926373..f73e57f6e3 100644
--- a/src/lib/efl_wl/Efl_Wl.h
+++ b/src/lib/efl_wl/Efl_Wl.h
@@ -204,12 +204,11 @@ EAPI Evas_Object *efl_wl_extracted_surface_extracted_parent_get(Evas_Object *sur
204 * @param seat The seat to set the keymap for, NULL to set the keymap for all seats 204 * @param seat The seat to set the keymap for, NULL to set the keymap for all seats
205 * @param keymap The xkb_keymap object to use 205 * @param keymap The xkb_keymap object to use
206 * @param state The xkb_state object to use 206 * @param state The xkb_state object to use
207 * @param fd The fd created from a mmapped xkb_keymap 207 * @param str The string containing the keymap
208 * @param size The size of the xkb_keymap memory
209 * @param wl_key_array A pointer to the wl_array in which keys are stored 208 * @param wl_key_array A pointer to the wl_array in which keys are stored
210 * @since 1.21 209 * @since 1.21
211 */ 210 */
212EAPI void efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int fd, size_t size, void *wl_key_array); 211EAPI void efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, char *str, void *wl_key_array);
213 212
214/** 213/**
215 * Set the key repeat rate for a seat in the compositor 214 * Set the key repeat rate for a seat in the compositor
diff --git a/src/lib/efl_wl/efl_wl.c b/src/lib/efl_wl/efl_wl.c
index 0da7d8c374..15e2ec0465 100644
--- a/src/lib/efl_wl/efl_wl.c
+++ b/src/lib/efl_wl/efl_wl.c
@@ -205,9 +205,8 @@ typedef struct Comp_Seat
205 struct xkb_context *context; 205 struct xkb_context *context;
206 struct xkb_keymap *keymap; 206 struct xkb_keymap *keymap;
207 struct xkb_state *state; 207 struct xkb_state *state;
208 char *keymap_mem; 208 char *keymap_str;
209 int keymap_mem_size; 209 int keymap_str_size;
210 int keymap_fd;
211 int repeat_rate; 210 int repeat_rate;
212 int repeat_delay; 211 int repeat_delay;
213 Eina_Hash *resources; 212 Eina_Hash *resources;
@@ -3677,6 +3676,48 @@ seat_update_caps(Comp_Seat *s, struct wl_resource *res)
3677 wl_seat_send_capabilities(res, caps); 3676 wl_seat_send_capabilities(res, caps);
3678} 3677}
3679 3678
3679static int
3680anonymous_fd_get(off_t size)
3681{
3682 Eina_Tmpstr *file;
3683 int fd;
3684
3685 fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
3686 if (fd < 0)
3687 {
3688 EINA_LOG_ERR("mkstemp failed!\n");
3689 return - 1;
3690 }
3691 if (!eina_file_close_on_exec(fd, 1))
3692 {
3693 EINA_LOG_ERR("Failed to set CLOEXEC on fd %d\n", fd);
3694 close(fd);
3695 return - 1;
3696 }
3697 ftruncate(fd, size);
3698 eina_file_unlink(file);
3699 eina_tmpstr_del(file);
3700
3701 return fd;
3702}
3703
3704static void
3705_keymap_send(Comp_Seat *s, struct wl_resource *res)
3706{
3707 char *mem;
3708 int fd;
3709
3710 fd = anonymous_fd_get(s->kbd.keymap_str_size);
3711 EINA_SAFETY_ON_TRUE_RETURN(fd == -1);
3712
3713 mem = mmap(NULL, s->kbd.keymap_str_size,
3714 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
3715 memcpy(mem, s->kbd.keymap_str, s->kbd.keymap_str_size);
3716 munmap(mem, s->kbd.keymap_str_size);
3717 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, s->kbd.keymap_str_size);
3718 close(fd);
3719}
3720
3680static void 3721static void
3681seat_keymap_send(Comp_Seat *s) 3722seat_keymap_send(Comp_Seat *s)
3682{ 3723{
@@ -3688,7 +3729,7 @@ seat_keymap_send(Comp_Seat *s)
3688 Eina_List *ll; 3729 Eina_List *ll;
3689 struct wl_resource *res; 3730 struct wl_resource *res;
3690 EINA_LIST_FOREACH(l, ll, res) 3731 EINA_LIST_FOREACH(l, ll, res)
3691 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, s->kbd.keymap_fd, s->kbd.keymap_mem_size); 3732 _keymap_send(s, res);
3692 } 3733 }
3693 eina_iterator_free(it); 3734 eina_iterator_free(it);
3694} 3735}
@@ -3733,12 +3774,10 @@ seat_kbd_external_init(Comp_Seat *s)
3733static void 3774static void
3734seat_keymap_update(Comp_Seat *s) 3775seat_keymap_update(Comp_Seat *s)
3735{ 3776{
3736 char *str;
3737 Eina_Tmpstr *file;
3738 xkb_mod_mask_t latched = 0, locked = 0; 3777 xkb_mod_mask_t latched = 0, locked = 0;
3739 3778
3740 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size); 3779 s->kbd.keymap_str = NULL;
3741 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd); 3780 s->kbd.keymap_str_size = 0;
3742 3781
3743#ifdef HAVE_ECORE_X 3782#ifdef HAVE_ECORE_X
3744 if (!x11_kbd_keymap) 3783 if (!x11_kbd_keymap)
@@ -3753,8 +3792,8 @@ seat_keymap_update(Comp_Seat *s)
3753 if (!s->kbd.keymap) 3792 if (!s->kbd.keymap)
3754 { 3793 {
3755 s->kbd.state = NULL; 3794 s->kbd.state = NULL;
3756 s->kbd.keymap_fd = -1; 3795 s->kbd.keymap_str = NULL;
3757 s->kbd.keymap_mem = NULL; 3796 s->kbd.keymap_str_size = 0;
3758 return; 3797 return;
3759 } 3798 }
3760 3799
@@ -3763,36 +3802,8 @@ seat_keymap_update(Comp_Seat *s)
3763#ifdef HAVE_ECORE_X 3802#ifdef HAVE_ECORE_X
3764 } 3803 }
3765#endif 3804#endif
3766 str = xkb_map_get_as_string(s->kbd.keymap); 3805 s->kbd.keymap_str = xkb_map_get_as_string(s->kbd.keymap);
3767 s->kbd.keymap_mem_size = strlen(str) + 1; 3806 s->kbd.keymap_str_size = strlen(s->kbd.keymap_str) + 1;
3768 s->kbd.keymap_fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
3769 if (s->kbd.keymap_fd < 0)
3770 {
3771 EINA_LOG_ERR("mkstemp failed!\n");
3772 s->kbd.keymap_fd = -1;
3773 xkb_state_unref(s->kbd.state);
3774 s->kbd.state = NULL;
3775 return;
3776 }
3777 if (!eina_file_close_on_exec(s->kbd.keymap_fd, 1))
3778 {
3779 EINA_LOG_ERR("Failed to set CLOEXEC on fd %d\n", s->kbd.keymap_fd);
3780 close(s->kbd.keymap_fd);
3781 s->kbd.keymap_fd = -1;
3782 xkb_state_unref(s->kbd.state);
3783 s->kbd.state = NULL;
3784 return;
3785 }
3786 ftruncate(s->kbd.keymap_fd, s->kbd.keymap_mem_size);
3787 eina_file_unlink(file);
3788 eina_tmpstr_del(file);
3789 s->kbd.keymap_mem =
3790 mmap(NULL, s->kbd.keymap_mem_size + 1,
3791 PROT_READ | PROT_WRITE, MAP_SHARED, s->kbd.keymap_fd, 0);
3792
3793 memcpy(s->kbd.keymap_mem, str, s->kbd.keymap_mem_size);
3794 s->kbd.keymap_mem[s->kbd.keymap_mem_size] = 0;
3795 free(str);
3796 3807
3797 seat_keymap_send(s); 3808 seat_keymap_send(s);
3798} 3809}
@@ -3859,7 +3870,7 @@ seat_kbd_create(struct wl_client *client, struct wl_resource *resource, uint32_t
3859 if (!s->kbd.resources) s->kbd.resources = eina_hash_pointer_new(NULL); 3870 if (!s->kbd.resources) s->kbd.resources = eina_hash_pointer_new(NULL);
3860 eina_hash_list_append(s->kbd.resources, &client, res); 3871 eina_hash_list_append(s->kbd.resources, &client, res);
3861 3872
3862 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, s->kbd.keymap_fd, s->kbd.keymap_mem_size); 3873 _keymap_send(s, res);
3863 3874
3864 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) 3875 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
3865 wl_keyboard_send_repeat_info(res, s->kbd.repeat_rate, s->kbd.repeat_delay); 3876 wl_keyboard_send_repeat_info(res, s->kbd.repeat_rate, s->kbd.repeat_delay);
@@ -4086,8 +4097,8 @@ seat_kbd_destroy(Comp_Seat *s)
4086#ifdef HAVE_ECORE_X 4097#ifdef HAVE_ECORE_X
4087 } 4098 }
4088#endif 4099#endif
4089 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size); 4100 s->kbd.keymap_str = NULL;
4090 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd); 4101 s->kbd.keymap_str_size = 0;
4091 wl_array_release(&s->kbd.keys); 4102 wl_array_release(&s->kbd.keys);
4092} 4103}
4093 4104
@@ -4481,7 +4492,6 @@ comp_seats_proxy(Comp *c)
4481 s = calloc(1, sizeof(Comp_Seat)); 4492 s = calloc(1, sizeof(Comp_Seat));
4482 s->c = c; 4493 s->c = c;
4483 s->dev = dev; 4494 s->dev = dev;
4484 s->kbd.keymap_fd = -1;
4485 efl_ref(s->dev); 4495 efl_ref(s->dev);
4486 if (c->parent_disp) 4496 if (c->parent_disp)
4487 comp_seat_proxy_update(s); 4497 comp_seat_proxy_update(s);
@@ -5945,7 +5955,7 @@ efl_wl_extracted_surface_extracted_parent_get(Evas_Object *surface)
5945} 5955}
5946 5956
5947void 5957void
5948efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int fd, size_t size, void *key_array) 5958efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, char *str, void *key_array)
5949{ 5959{
5950 Comp *c; 5960 Comp *c;
5951 Comp_Seat *s; 5961 Comp_Seat *s;
@@ -5954,7 +5964,7 @@ efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int fd, size_t s
5954 c = evas_object_smart_data_get(obj); 5964 c = evas_object_smart_data_get(obj);
5955 EINA_INLIST_FOREACH(c->seats, s) 5965 EINA_INLIST_FOREACH(c->seats, s)
5956 { 5966 {
5957 if (!seat) efl_wl_seat_keymap_set(obj, s->dev, state, fd, size, key_array); 5967 if (!seat) efl_wl_seat_keymap_set(obj, s->dev, state, str, key_array);
5958 else if (s->dev == seat) break; 5968 else if (s->dev == seat) break;
5959 } 5969 }
5960 if (!seat) return; 5970 if (!seat) return;
@@ -5963,11 +5973,13 @@ efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int fd, size_t s
5963 s->kbd.external = 1; 5973 s->kbd.external = 1;
5964 s->kbd.keys_external = key_array; 5974 s->kbd.keys_external = key_array;
5965 s->kbd.state = state; 5975 s->kbd.state = state;
5966 s->kbd.keymap_fd = fd; 5976 s->kbd.keymap_str = str;
5967 s->kbd.keymap_mem_size = size; 5977 if (str)
5978 s->kbd.keymap_str_size = strlen(str) + 1;
5979 else
5980 s->kbd.keymap_str_size = 0;
5968 s->kbd.context = NULL; 5981 s->kbd.context = NULL;
5969 s->kbd.keymap = NULL; 5982 s->kbd.keymap = NULL;
5970 s->kbd.keymap_mem = NULL;
5971 if (s->keyboard) 5983 if (s->keyboard)
5972 seat_kbd_external_init(s); 5984 seat_kbd_external_init(s);
5973} 5985}