discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=6fe7e1155db768dcafa9f24af8f6b98230974813

commit 6fe7e1155db768dcafa9f24af8f6b98230974813
Author: Derek Foreman <derek.foreman.sams...@gmail.com>
Date:   Fri Aug 17 12:46:39 2018 -0400

    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
---
 src/lib/efl_wl/Efl_Wl.h |   5 +--
 src/lib/efl_wl/efl_wl.c | 110 +++++++++++++++++++++++++++---------------------
 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
  * @param seat The seat to set the keymap for, NULL to set the keymap for all 
seats
  * @param keymap The xkb_keymap object to use
  * @param state The xkb_state object to use
- * @param fd The fd created from a mmapped xkb_keymap
- * @param size The size of the xkb_keymap memory
+ * @param str The string containing the keymap
  * @param wl_key_array A pointer to the wl_array in which keys are stored
  * @since 1.21
  */
-EAPI void efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int 
fd, size_t size, void *wl_key_array);
+EAPI void efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, char 
*str, void *wl_key_array);
 
 /**
  * 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
       struct xkb_context *context;
       struct xkb_keymap *keymap;
       struct xkb_state *state;
-      char *keymap_mem;
-      int keymap_mem_size;
-      int keymap_fd;
+      char *keymap_str;
+      int keymap_str_size;
       int repeat_rate;
       int repeat_delay;
       Eina_Hash *resources;
@@ -3677,6 +3676,48 @@ seat_update_caps(Comp_Seat *s, struct wl_resource *res)
        wl_seat_send_capabilities(res, caps);
 }
 
+static int
+anonymous_fd_get(off_t size)
+{
+   Eina_Tmpstr *file;
+   int fd;
+
+   fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
+   if (fd < 0)
+     {
+        EINA_LOG_ERR("mkstemp failed!\n");
+        return - 1;
+     }
+   if (!eina_file_close_on_exec(fd, 1))
+     {
+        EINA_LOG_ERR("Failed to set CLOEXEC on fd %d\n", fd);
+        close(fd);
+        return - 1;
+     }
+   ftruncate(fd, size);
+   eina_file_unlink(file);
+   eina_tmpstr_del(file);
+
+   return fd;
+}
+
+static void
+_keymap_send(Comp_Seat *s, struct wl_resource *res)
+{
+   char *mem;
+   int fd;
+
+   fd = anonymous_fd_get(s->kbd.keymap_str_size);
+   EINA_SAFETY_ON_TRUE_RETURN(fd == -1);
+
+   mem = mmap(NULL, s->kbd.keymap_str_size,
+              PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+   memcpy(mem, s->kbd.keymap_str, s->kbd.keymap_str_size);
+   munmap(mem, s->kbd.keymap_str_size);
+   wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, 
s->kbd.keymap_str_size);
+   close(fd);
+}
+
 static void
 seat_keymap_send(Comp_Seat *s)
 {
@@ -3688,7 +3729,7 @@ seat_keymap_send(Comp_Seat *s)
         Eina_List *ll;
         struct wl_resource *res;
         EINA_LIST_FOREACH(l, ll, res)
-          wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, 
s->kbd.keymap_fd, s->kbd.keymap_mem_size);
+          _keymap_send(s, res);
      }
    eina_iterator_free(it);
 }
@@ -3733,12 +3774,10 @@ seat_kbd_external_init(Comp_Seat *s)
 static void
 seat_keymap_update(Comp_Seat *s)
 {
-   char *str;
-   Eina_Tmpstr *file;
    xkb_mod_mask_t latched = 0, locked = 0;
 
-   if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
-   if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
+   s->kbd.keymap_str = NULL;
+   s->kbd.keymap_str_size = 0;
 
 #ifdef HAVE_ECORE_X
    if (!x11_kbd_keymap)
@@ -3753,8 +3792,8 @@ seat_keymap_update(Comp_Seat *s)
         if (!s->kbd.keymap)
           {
              s->kbd.state = NULL;
-             s->kbd.keymap_fd = -1;
-             s->kbd.keymap_mem = NULL;
+             s->kbd.keymap_str = NULL;
+             s->kbd.keymap_str_size = 0;
              return;
           }
 
@@ -3763,36 +3802,8 @@ seat_keymap_update(Comp_Seat *s)
 #ifdef HAVE_ECORE_X
      }
 #endif
-   str = xkb_map_get_as_string(s->kbd.keymap);
-   s->kbd.keymap_mem_size = strlen(str) + 1;
-   s->kbd.keymap_fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
-   if (s->kbd.keymap_fd < 0)
-     {
-        EINA_LOG_ERR("mkstemp failed!\n");
-        s->kbd.keymap_fd = -1;
-        xkb_state_unref(s->kbd.state);
-        s->kbd.state = NULL;
-        return;
-     }
-   if (!eina_file_close_on_exec(s->kbd.keymap_fd, 1))
-     {
-        EINA_LOG_ERR("Failed to set CLOEXEC on fd %d\n", s->kbd.keymap_fd);
-        close(s->kbd.keymap_fd);
-        s->kbd.keymap_fd = -1;
-        xkb_state_unref(s->kbd.state);
-        s->kbd.state = NULL;
-        return;
-     }
-   ftruncate(s->kbd.keymap_fd, s->kbd.keymap_mem_size);
-   eina_file_unlink(file);
-   eina_tmpstr_del(file);
-   s->kbd.keymap_mem =
-     mmap(NULL, s->kbd.keymap_mem_size + 1,
-       PROT_READ | PROT_WRITE, MAP_SHARED, s->kbd.keymap_fd, 0);
-
-   memcpy(s->kbd.keymap_mem, str, s->kbd.keymap_mem_size);
-   s->kbd.keymap_mem[s->kbd.keymap_mem_size] = 0;
-   free(str);
+   s->kbd.keymap_str = xkb_map_get_as_string(s->kbd.keymap);
+   s->kbd.keymap_str_size = strlen(s->kbd.keymap_str) + 1;
 
    seat_keymap_send(s);
 }
@@ -3859,7 +3870,7 @@ seat_kbd_create(struct wl_client *client, struct 
wl_resource *resource, uint32_t
    if (!s->kbd.resources) s->kbd.resources = eina_hash_pointer_new(NULL);
    eina_hash_list_append(s->kbd.resources, &client, res);
 
-   wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, 
s->kbd.keymap_fd, s->kbd.keymap_mem_size);
+   _keymap_send(s, res);
 
    if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
      wl_keyboard_send_repeat_info(res, s->kbd.repeat_rate, 
s->kbd.repeat_delay);
@@ -4086,8 +4097,8 @@ seat_kbd_destroy(Comp_Seat *s)
 #ifdef HAVE_ECORE_X
      }
 #endif
-   if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
-   if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
+   s->kbd.keymap_str = NULL;
+   s->kbd.keymap_str_size = 0;
    wl_array_release(&s->kbd.keys);
 }
 
@@ -4481,7 +4492,6 @@ comp_seats_proxy(Comp *c)
         s = calloc(1, sizeof(Comp_Seat));
         s->c = c;
         s->dev = dev;
-        s->kbd.keymap_fd = -1;
         efl_ref(s->dev);
         if (c->parent_disp)
           comp_seat_proxy_update(s);
@@ -5945,7 +5955,7 @@ efl_wl_extracted_surface_extracted_parent_get(Evas_Object 
*surface)
 }
 
 void
-efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int fd, size_t 
size, void *key_array)
+efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, char *str, 
void *key_array)
 {
    Comp *c;
    Comp_Seat *s;
@@ -5954,7 +5964,7 @@ efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void 
*state, int fd, size_t s
    c = evas_object_smart_data_get(obj);
    EINA_INLIST_FOREACH(c->seats, s)
      {
-        if (!seat) efl_wl_seat_keymap_set(obj, s->dev, state, fd, size, 
key_array);
+        if (!seat) efl_wl_seat_keymap_set(obj, s->dev, state, str, key_array);
         else if (s->dev == seat) break;
      }
    if (!seat) return;
@@ -5963,11 +5973,13 @@ efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void 
*state, int fd, size_t s
    s->kbd.external = 1;
    s->kbd.keys_external = key_array;
    s->kbd.state = state;
-   s->kbd.keymap_fd = fd;
-   s->kbd.keymap_mem_size = size;
+   s->kbd.keymap_str = str;
+   if (str)
+     s->kbd.keymap_str_size = strlen(str) + 1;
+   else
+     s->kbd.keymap_str_size = 0;
    s->kbd.context = NULL;
    s->kbd.keymap = NULL;
-   s->kbd.keymap_mem = NULL;
    if (s->keyboard)
      seat_kbd_external_init(s);
 }

-- 


Reply via email to