[PATCH v2] ui: Fix memory leak in qemu_xkeymap_mapping_table()

Philippe Mathieu-Daudé posted 1 patch 3 years ago
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20210430155009.259755-1-philmd@redhat.com
ui/x_keymap.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
[PATCH v2] ui: Fix memory leak in qemu_xkeymap_mapping_table()
Posted by Philippe Mathieu-Daudé 3 years ago
Refactor qemu_xkeymap_mapping_table() to have a single exit point,
so we can easily free the memory allocated by XGetAtomName().

This fixes when running a binary configured with --enable-sanitizers:

  Direct leak of 22 byte(s) in 1 object(s) allocated from:
      #0 0x561344a7473f in malloc (qemu-system-x86_64+0x1dab73f)
      #1 0x7fa4d9dc08aa in XGetAtomName (/lib64/libX11.so.6+0x2a8aa)

Fixes: 2ec78706d18 ("ui: convert GTK and SDL1 frontends to keycodemapdb")
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 ui/x_keymap.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/ui/x_keymap.c b/ui/x_keymap.c
index 555086fb6bd..2ce7b899615 100644
--- a/ui/x_keymap.c
+++ b/ui/x_keymap.c
@@ -56,6 +56,7 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
 {
     XkbDescPtr desc;
     const gchar *keycodes = NULL;
+    const guint16 *map;
 
     /* There is no easy way to determine what X11 server
      * and platform & keyboard driver is in use. Thus we
@@ -83,21 +84,21 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
     if (check_for_xwin(dpy)) {
         trace_xkeymap_keymap("xwin");
         *maplen = qemu_input_map_xorgxwin_to_qcode_len;
-        return qemu_input_map_xorgxwin_to_qcode;
+        map = qemu_input_map_xorgxwin_to_qcode;
     } else if (check_for_xquartz(dpy)) {
         trace_xkeymap_keymap("xquartz");
         *maplen = qemu_input_map_xorgxquartz_to_qcode_len;
-        return qemu_input_map_xorgxquartz_to_qcode;
+        map = qemu_input_map_xorgxquartz_to_qcode;
     } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) ||
                (XKeysymToKeycode(dpy, XK_Page_Up) == 0x70)) {
         trace_xkeymap_keymap("evdev");
         *maplen = qemu_input_map_xorgevdev_to_qcode_len;
-        return qemu_input_map_xorgevdev_to_qcode;
+        map = qemu_input_map_xorgevdev_to_qcode;
     } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) ||
                (XKeysymToKeycode(dpy, XK_Page_Up) == 0x63)) {
         trace_xkeymap_keymap("kbd");
         *maplen = qemu_input_map_xorgkbd_to_qcode_len;
-        return qemu_input_map_xorgkbd_to_qcode;
+        map = qemu_input_map_xorgkbd_to_qcode;
     } else {
         trace_xkeymap_keymap("NULL");
         g_warning("Unknown X11 keycode mapping '%s'.\n"
@@ -109,6 +110,10 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
                   "  - xprop -root\n"
                   "  - xdpyinfo\n",
                   keycodes ? keycodes : "<null>");
-        return NULL;
+        map = NULL;
     }
+    if (keycodes) {
+        XFree((void *)keycodes);
+    }
+    return map;
 }
-- 
2.26.3

Re: [PATCH v2] ui: Fix memory leak in qemu_xkeymap_mapping_table()
Posted by Laurent Vivier 3 years ago
Le 30/04/2021 à 17:50, Philippe Mathieu-Daudé a écrit :
> Refactor qemu_xkeymap_mapping_table() to have a single exit point,
> so we can easily free the memory allocated by XGetAtomName().
> 
> This fixes when running a binary configured with --enable-sanitizers:
> 
>   Direct leak of 22 byte(s) in 1 object(s) allocated from:
>       #0 0x561344a7473f in malloc (qemu-system-x86_64+0x1dab73f)
>       #1 0x7fa4d9dc08aa in XGetAtomName (/lib64/libX11.so.6+0x2a8aa)
> 
> Fixes: 2ec78706d18 ("ui: convert GTK and SDL1 frontends to keycodemapdb")
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
>  ui/x_keymap.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
>

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

Re: [PATCH v2] ui: Fix memory leak in qemu_xkeymap_mapping_table()
Posted by Laurent Vivier 3 years ago
Le 30/04/2021 à 17:50, Philippe Mathieu-Daudé a écrit :
> Refactor qemu_xkeymap_mapping_table() to have a single exit point,
> so we can easily free the memory allocated by XGetAtomName().
> 
> This fixes when running a binary configured with --enable-sanitizers:
> 
>   Direct leak of 22 byte(s) in 1 object(s) allocated from:
>       #0 0x561344a7473f in malloc (qemu-system-x86_64+0x1dab73f)
>       #1 0x7fa4d9dc08aa in XGetAtomName (/lib64/libX11.so.6+0x2a8aa)
> 
> Fixes: 2ec78706d18 ("ui: convert GTK and SDL1 frontends to keycodemapdb")
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
>  ui/x_keymap.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/ui/x_keymap.c b/ui/x_keymap.c
> index 555086fb6bd..2ce7b899615 100644
> --- a/ui/x_keymap.c
> +++ b/ui/x_keymap.c
> @@ -56,6 +56,7 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
>  {
>      XkbDescPtr desc;
>      const gchar *keycodes = NULL;
> +    const guint16 *map;
>  
>      /* There is no easy way to determine what X11 server
>       * and platform & keyboard driver is in use. Thus we
> @@ -83,21 +84,21 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
>      if (check_for_xwin(dpy)) {
>          trace_xkeymap_keymap("xwin");
>          *maplen = qemu_input_map_xorgxwin_to_qcode_len;
> -        return qemu_input_map_xorgxwin_to_qcode;
> +        map = qemu_input_map_xorgxwin_to_qcode;
>      } else if (check_for_xquartz(dpy)) {
>          trace_xkeymap_keymap("xquartz");
>          *maplen = qemu_input_map_xorgxquartz_to_qcode_len;
> -        return qemu_input_map_xorgxquartz_to_qcode;
> +        map = qemu_input_map_xorgxquartz_to_qcode;
>      } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) ||
>                 (XKeysymToKeycode(dpy, XK_Page_Up) == 0x70)) {
>          trace_xkeymap_keymap("evdev");
>          *maplen = qemu_input_map_xorgevdev_to_qcode_len;
> -        return qemu_input_map_xorgevdev_to_qcode;
> +        map = qemu_input_map_xorgevdev_to_qcode;
>      } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) ||
>                 (XKeysymToKeycode(dpy, XK_Page_Up) == 0x63)) {
>          trace_xkeymap_keymap("kbd");
>          *maplen = qemu_input_map_xorgkbd_to_qcode_len;
> -        return qemu_input_map_xorgkbd_to_qcode;
> +        map = qemu_input_map_xorgkbd_to_qcode;
>      } else {
>          trace_xkeymap_keymap("NULL");
>          g_warning("Unknown X11 keycode mapping '%s'.\n"
> @@ -109,6 +110,10 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
>                    "  - xprop -root\n"
>                    "  - xdpyinfo\n",
>                    keycodes ? keycodes : "<null>");
> -        return NULL;
> +        map = NULL;
>      }
> +    if (keycodes) {
> +        XFree((void *)keycodes);
> +    }
> +    return map;
>  }
> 

Applied to my trivial-patches branch.

Thanks,
Laurent