-----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;
}