-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hi,

while trying to find a reason for the crash I've been seeing with rc2, I noticed
that awesome doesn't properly handle invalid _NET_WM_ICONs. It just assumes the
width and height reported in the property is valid, even if the property is much
shorter than those values would make you think.
The attached C app (which is based on some code from farhaven) shows this. It
sets some invalid _NET_WM_ICON property for it's window and this results in the
following under valgrind:

==18057== Source and destination overlap in memcpy(0x7E598E0, 0x7E597C0, 4092)
==18057==    at 0x4A0954A: memcpy (mc_replace_strmem.c:402)
==18057==    by 0x3B6F810924: imlib_create_image_using_copied_data (in
/usr/lib/libImlib2.so.1.4.2)
==18057==    by 0x4317C7: image_new_from_argb32 (image.c:133)
==18057==    by 0x41B8EF: ewmh_window_icon_get_reply (ewmh.c:667)
==18057==    by 0x4129A5: client_manage (client.c:502)
==18057==    by 0x417D90: event_handle_maprequest (event.c:645)
==18057==    by 0x40DFDC: a_xcb_check_cb (awesome.c:203)
==18057==    by 0x32AE607216: ev_loop (in /usr/lib/libev.so.3.0.0)
==18057==    by 0x40E8A6: main (awesome.c:536)
==18057==
==18057== Invalid read of size 1
==18057==    at 0x4A09570: memcpy (mc_replace_strmem.c:402)
==18057==    by 0x3B6F810924: imlib_create_image_using_copied_data (in
/usr/lib/libImlib2.so.1.4.2)
==18057==    by 0x4317C7: image_new_from_argb32 (image.c:133)
==18057==    by 0x41B8EF: ewmh_window_icon_get_reply (ewmh.c:667)
==18057==    by 0x4129A5: client_manage (client.c:502)
==18057==    by 0x417D90: event_handle_maprequest (event.c:645)
==18057==    by 0x40DFDC: a_xcb_check_cb (awesome.c:203)
==18057==    by 0x32AE607216: ev_loop (in /usr/lib/libev.so.3.0.0)
==18057==    by 0x40E8A6: main (awesome.c:536)
==18057==  Address 0x7e598df is 1 bytes before a block of size 4,092 alloc'd
==18057==    at 0x4A0891E: malloc (vg_replace_malloc.c:207)
==18057==    by 0x3B6F810912: imlib_create_image_using_copied_data (in
/usr/lib/libImlib2.so.1.4.2)
==18057==    by 0x4317C7: image_new_from_argb32 (image.c:133)
==18057==    by 0x41B8EF: ewmh_window_icon_get_reply (ewmh.c:667)
==18057==    by 0x4129A5: client_manage (client.c:502)
==18057==    by 0x417D90: event_handle_maprequest (event.c:645)
==18057==    by 0x40DFDC: a_xcb_check_cb (awesome.c:203)
==18057==    by 0x32AE607216: ev_loop (in /usr/lib/libev.so.3.0.0)
==18057==    by 0x40E8A6: main (awesome.c:536)

If no one comes up with a patch first, I'll give it a try on thursday (no time
before then).
So far it looks like ewmh_window_icon_get_reply() needs some check like this (+
handling integer overflows somehow):
 if (width * height + 2 > length) error()

Cheers,
Uli
- --
"Do you know that books smell like nutmeg or some spice from a foreign land?"
                                                  -- Faber in Fahrenheit 451
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iQEcBAEBCAAGBQJKCTp/AAoJECLkKOvLj8sG8QUH/3stzkdN25dyU3UOevRnwELA
/jHS012sKLEl2CwYkdlWWlDFq17DxvYlXRshzZNK0fB4U91r/qjV4RmJKXjalB5x
RENTdCPZBDUE2x1iSfkRH47V945bak2mj6eKhFQfyK7vy9TwOuJrCbM7GEnRHRnf
fwx555TaA0g1ADArI3c6RUqJtcDlN6ojrsJYXidpD/bTicv2spHGZ57JOhQXFFPS
35MDzU+v8a0dQyN5F98JyLlamlITD4fPEI7Dzyhef6FyEK0oPwLLPPzDfVbUc61F
KZAjBGlaeIDSf9+bdP43gH96hO9leQtT1XtL8M/R6VrxOwBnHw5XvvRDQuDx+eI=
=NrvI
-----END PGP SIGNATURE-----
/* stolen from wikipedia and modified a bit,
 * compile like this:
 * gcc -o test test.c -lxcb -std=c99
 */

#include <xcb/xcb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
    int                  i;
    xcb_connection_t    *c;
    xcb_screen_t        *s;
    xcb_window_t         w;
    xcb_gcontext_t       g;
    xcb_generic_event_t *e;
    uint32_t             mask;
    uint32_t             values[2];
    int                  done = 0;
    xcb_rectangle_t      r = { 20, 20, 60, 60 };

    const uint32_t data[5] = { 31, 33, 73, 13, 37 };
    const char *CARD = "CARDINAL";
    const char *ICON = "_NET_WM_ICON";
    xcb_atom_t cardinal, icon;

    c = xcb_connect(NULL,NULL);
    if (xcb_connection_has_error(c))
    {
        printf("Cannot open display\n");
        exit(1);
    }

    s = xcb_setup_roots_iterator( xcb_get_setup(c) ).data;
    fprintf(stderr, "width=%d height=%d\n", s->width_in_pixels, s->height_in_pixels);

    cardinal = xcb_intern_atom_reply(c, xcb_intern_atom_unchecked(c, 0, strlen(CARD), CARD), NULL)->atom;
    icon = xcb_intern_atom_reply(c, xcb_intern_atom_unchecked(c, 0, strlen(ICON), ICON), NULL)->atom;

    mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
    values[0] = s->white_pixel;
    values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;

    w = xcb_generate_id(c);
    xcb_create_window(c, s->root_depth, w, s->root,
                        (10 * i) % s->width_in_pixels, (10 * i) % s->height_in_pixels, 100, 100, 1,
                        XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual,
                        mask, values);
    xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, icon, cardinal, 32, sizeof(data) / 4, data);

    xcb_map_window(c, w);

    xcb_flush(c);

    printf("Done with setup\n");

    while (!done && (e = xcb_wait_for_event(c)))
    {
        switch (e->response_type & ~0x80)
        {
            case XCB_KEY_PRESS:
                done = 1;
                break;
        }
        free(e);
    }

    xcb_disconnect(c);

    return 0;
}

Reply via email to