derekf pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=a0370010311b7c46b3b0475e7a9319bfc920802a

commit a0370010311b7c46b3b0475e7a9319bfc920802a
Author: Derek Foreman <[email protected]>
Date:   Fri Aug 17 12:28:49 2018 -0500

    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: zmike, devilhorns
    
    Subscribers: cedric
    
    Tags: #enlightenment-git
    
    Differential Revision: https://phab.enlightenment.org/D6861
---
 src/bin/e_comp_wl.h                    |  7 +--
 src/bin/e_comp_wl_input.c              | 84 +++++++++++++++++-----------------
 src/bin/e_comp_wl_input.h              |  3 ++
 src/bin/e_gadget_runner.c              |  4 +-
 src/modules/wl_text_input/e_mod_main.c |  4 +-
 5 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index 11bc1ff88..e234e5d44 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -266,9 +266,8 @@ struct _E_Comp_Wl_Data
         struct xkb_keymap *keymap;
         struct xkb_context *context;
         struct xkb_state *state;
-        int fd;
-        size_t size;
-        char *area;
+        char *map_string;
+        int map_size;
      } xkb;
 
    E_Comp_Wl_Extension_Data *extensions;
@@ -447,6 +446,8 @@ e_policy_wl_aux_message_send(E_Client *ec,
                              const char *val,
                              Eina_List *options);
 
+E_API void e_comp_wl_input_keymap_send(struct wl_resource *res);
+
 # ifndef HAVE_WAYLAND_ONLY
 EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec);
 static inline E_Comp_X_Client_Data *
diff --git a/src/bin/e_comp_wl_input.c b/src/bin/e_comp_wl_input.c
index d5870feb0..1f4a9ede9 100644
--- a/src/bin/e_comp_wl_input.c
+++ b/src/bin/e_comp_wl_input.c
@@ -227,8 +227,7 @@ _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, 
struct wl_resource *r
      wl_keyboard_send_repeat_info(res, e_config->keyboard.repeat_rate, 
e_config->keyboard.repeat_delay);
 
    /* send current keymap */
-   wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
-                           e_comp_wl->xkb.fd, e_comp_wl->xkb.size);
+   e_comp_wl_input_keymap_send(res);
 
    /* if the client owns the focused surface, we need to send an enter */
    focused = e_client_focused_get();
@@ -317,13 +316,14 @@ _e_comp_wl_input_cb_bind_seat(struct wl_client *client, 
void *data EINA_UNUSED,
      wl_seat_send_name(res, e_comp_wl->seat.name);
 }
 
-static int
-_e_comp_wl_input_keymap_fd_get(off_t size)
+int
+_e_comp_wl_input_keymap_fd_get(void)
 {
    int fd = 0, blen = 0, len = 0;
    const char *path;
    char tmp[PATH_MAX];
    long flags;
+   void *mm;
 
    blen = sizeof(tmp) - 1;
 
@@ -354,13 +354,25 @@ _e_comp_wl_input_keymap_fd_get(off_t size)
         return -1;
      }
 
-   if (ftruncate(fd, size) < 0)
+   if (ftruncate(fd, e_comp_wl->xkb.map_size) < 0)
      {
         close(fd);
         return -1;
      }
 
    unlink(tmp);
+   mm = mmap(NULL, e_comp_wl->xkb.map_size, (PROT_READ | PROT_WRITE),
+             MAP_SHARED, fd, 0);
+   if (mm == MAP_FAILED)
+     {
+        ERR("Failed to mmap keymap area: %m");
+        close(fd);
+        return -1;
+     }
+
+   memcpy(mm, e_comp_wl->xkb.map_string, e_comp_wl->xkb.map_size);
+   munmap(mm, e_comp_wl->xkb.map_size);
+
    return fd;
 }
 
@@ -389,6 +401,21 @@ _e_comp_wl_input_state_update(void)
                          0, 0);
 }
 
+void
+e_comp_wl_input_keymap_send(struct wl_resource *res)
+{
+   int fd;
+
+   fd = _e_comp_wl_input_keymap_fd_get();
+   if (fd == -1)
+     return;
+
+   wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
+                           fd, e_comp_wl->xkb.map_size);
+
+   close(fd);
+}
+
 static void
 nested_keymap_update(void)
 {
@@ -396,13 +423,12 @@ nested_keymap_update(void)
    Evas_Object *obj;
 
    EINA_LIST_FOREACH(e_comp_wl->efl_wls, l, obj)
-     efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, 
e_comp_wl->xkb.fd, e_comp_wl->xkb.size, &e_comp_wl->kbd.keys);
+     efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, 
e_comp_wl->xkb.map_string, &e_comp_wl->kbd.keys);
 }
 
 static void
 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap)
 {
-   char *tmp;
    struct wl_resource *res;
    Eina_List *l;
 
@@ -410,11 +436,9 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap)
    if (e_comp_wl->xkb.keymap)
      xkb_map_unref(e_comp_wl->xkb.keymap);
 
-   /* unmap any existing keyboard area */
-   if (e_comp_wl->xkb.area)
-     munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
-   if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
-
+   /* free any existing keyboard map string */
+   free(e_comp_wl->xkb.map_string);
+   e_comp_wl->xkb.map_string = NULL;
 
    /* increment keymap reference */
    e_comp_wl->xkb.keymap = keymap;
@@ -422,39 +446,17 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap)
    /* update the state */
    _e_comp_wl_input_state_update();
 
-   if (!(tmp = xkb_map_get_as_string(keymap)))
+   if (!(e_comp_wl->xkb.map_string = xkb_map_get_as_string(keymap)))
      {
         ERR("Could not get keymap string");
         return;
      }
 
-   e_comp_wl->xkb.size = strlen(tmp) + 1;
-   e_comp_wl->xkb.fd =
-     _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size);
-   if (e_comp_wl->xkb.fd < 0)
-     {
-        ERR("Could not create keymap file");
-        free(tmp);
-        return;
-     }
-
-   e_comp_wl->xkb.area =
-     mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE),
-          MAP_SHARED, e_comp_wl->xkb.fd, 0);
-   if (e_comp_wl->xkb.area == MAP_FAILED)
-     {
-        ERR("Failed to mmap keymap area: %m");
-        free(tmp);
-        return;
-     }
-
-   strcpy(e_comp_wl->xkb.area, tmp);
-   free(tmp);
+   e_comp_wl->xkb.map_size = strlen(e_comp_wl->xkb.map_string) + 1;
 
    /* send updated keymap */
    EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
-     wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
-                             e_comp_wl->xkb.fd, e_comp_wl->xkb.size);
+     e_comp_wl_input_keymap_send(res);
 
    /* update modifiers */
    e_comp_wl_input_keyboard_modifiers_update();
@@ -468,8 +470,6 @@ e_comp_wl_input_init(void)
    if (!e_comp_wl->seat.name)
      e_comp_wl->seat.name = "seat0";
 
-   e_comp_wl->xkb.fd = -1;
-
    /* create the global resource for input seat */
    e_comp_wl->seat.global =
      wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
@@ -524,10 +524,8 @@ e_comp_wl_input_shutdown(void)
    /* destroy e_comp_wl->kbd.keys array */
    wl_array_release(&e_comp_wl->kbd.keys);
 
-   /* unmap any existing keyboard area */
-   if (e_comp_wl->xkb.area)
-     munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
-   if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
+   /* free the string copy of the keyboard map */
+   free(e_comp_wl->xkb.map_string);
 
    /* unreference any existing keyboard state */
    if (e_comp_wl->xkb.state)
diff --git a/src/bin/e_comp_wl_input.h b/src/bin/e_comp_wl_input.h
index e726aa0c1..2989d5b75 100644
--- a/src/bin/e_comp_wl_input.h
+++ b/src/bin/e_comp_wl_input.h
@@ -36,5 +36,8 @@ E_API void 
e_comp_wl_input_keymap_index_set(xkb_layout_index_t index);
 E_API void e_comp_wl_input_keymap_set(const char *rules, const char *model, 
const char *layout, const char *variant, const char *options);
 
 E_API void e_comp_wl_input_keyboard_event_generate(const char *key, int mods, 
Eina_Bool up);
+
+EINTERN int _e_comp_wl_input_keymap_fd_get(void);
+
 # endif
 #endif
diff --git a/src/bin/e_gadget_runner.c b/src/bin/e_gadget_runner.c
index cec75af4d..1d98f133c 100644
--- a/src/bin/e_gadget_runner.c
+++ b/src/bin/e_gadget_runner.c
@@ -786,7 +786,7 @@ popup_added(void *data, Evas_Object *obj EINA_UNUSED, void 
*event_info)
 static void
 seat_added(void *data EINA_UNUSED, Evas_Object *obj, void *event_info 
EINA_UNUSED)
 {
-   efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, e_comp_wl->xkb.fd, 
e_comp_wl->xkb.size, &e_comp_wl->kbd.keys);
+   efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, 
e_comp_wl->xkb.map_string, &e_comp_wl->kbd.keys);
    efl_wl_seat_key_repeat_set(obj, NULL, e_config->keyboard.repeat_rate, 
e_config->keyboard.repeat_delay);
 }
 
@@ -875,7 +875,7 @@ gadget_create(Evas_Object *parent, Config_Item *ci, int 
*id, E_Gadget_Site_Orien
    inst->obj = efl_wl_add(e_comp->evas);
    if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
      {
-        efl_wl_seat_keymap_set(inst->obj, NULL, e_comp_wl->xkb.state, 
e_comp_wl->xkb.fd, e_comp_wl->xkb.size, &e_comp_wl->kbd.keys);
+        efl_wl_seat_keymap_set(inst->obj, NULL, e_comp_wl->xkb.state, 
e_comp_wl->xkb.map_string, &e_comp_wl->kbd.keys);
         efl_wl_seat_key_repeat_set(inst->obj, NULL, 
e_config->keyboard.repeat_rate, e_config->keyboard.repeat_delay);
         e_comp_wl->efl_wls = eina_list_append(e_comp_wl->efl_wls, inst->obj);
      }
diff --git a/src/modules/wl_text_input/e_mod_main.c 
b/src/modules/wl_text_input/e_mod_main.c
index 90d550a97..324f43173 100644
--- a/src/modules/wl_text_input/e_mod_main.c
+++ b/src/modules/wl_text_input/e_mod_main.c
@@ -324,9 +324,7 @@ _e_text_input_method_context_cb_keyboard_grab(struct 
wl_client *client, struct w
    wl_resource_set_implementation(new_resource, NULL, context,
                                   
_e_text_input_method_context_keyboard_unbind);
 
-   wl_keyboard_send_keymap(new_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
-                           e_comp_wl->xkb.fd,
-                           e_comp_wl->xkb.size);
+   e_comp_wl_input_keymap_send(new_resource);
 
    context->kbd.resource = new_resource;
 

-- 


Reply via email to