Hello, After a few hours of investigation I've tracked down this bug. At least I've discovered what code causes Xserver to leak memory, when the bug is "exploited" by gpdf. It's as simple as the following:
cursor = gdk_cursor_new_for_display(display, GDK_WATCH); // ... // gdk_cursor_unref(cursor); This code gets repeated approx. twice as many times as there are pages in the pdf (when processing both bookmarks and thumbnails). While this is the bug in the gpdf itself (the cursor should not be set so many times), it reveals the bug in the X server. X footprint keeps growing because of repeatable memory allocations for the cursor and gdk_cursor_unref() failures to free that memory. However, this doesn't happen with all types of cursors. Only *animated* ones are affected (I base this hypothesis on my tests). Memory occupied by static cursors gets freed properly by the gdk_cursor_unref() routine. This explains why other people are not suffering from this bug. I've made a simple gtk program, which starts executing the code above infinite number times once you press the "Test memleak!" button (thus you will need to use CTRL+C or `kill` to terminate the program). Here it's the step-by-step guide to reproduce the memleak: 1. Make sure your "watch" cursor is the animated one or change the argument 2 of the gdk_cursor_new_for_display() accordingly to the cursor which is animated in the theme you're using. If neither is animated, you can obtain one from [1] or other source. I extracted the "watch" cursor from this theme and put it on my web site[2]. Simply place it into ~/.icons/<your current xcursor theme name (in case of "core", use "default")>/cursors/watch This should be enough to reproduce the bug without restarting X. 2. Compile memleak.c from [3] with the following command (you will need libgtk2.0-dev and its dependences for this): gcc memleak.c -o memleak -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/gtk-2.0/include -I/usr/lib/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -L/usr/lib -lgtk-x11-2.0 and start the program. 3. Press the "Test memleak!" button in the GUI and observe X server memory usage ("RES" field with `top`). If you have a fast pc, X should consume hundreds MBs of memory *very* quickly. 4. To kill the program use CTRL+C or `kill` (it's my first gtk program ever, so I haven't invested more time in making termination more sophisticated) Another interesting thing is that X seems to reuse the allocated memory for sequent cursor allocations in other programs (like another instance of `memleak`) once the program triggering the bug gets terminated. Test this by running several instances of `memleak` one after another. So for now till someone with more knowlegde of XFree86 code fixes the bug a simple workaround is to avoid animated cursors. There may be a bug in gdk_cursor_unref() too, I haven't checked the code. In any case, I think it's a big (security?) problem in the X server code, because any malicious app can make X server (which is generally running as root on most systems with DM) use large amounts of memory by repeatedly allocating memory for the cursor and not freeing it aftwerwards. It would be great if someone could test this test case on Xorg. Lots of distros include animated watch cursors by default these days, and if these are big, lots of people might be suffering from this bug. The "fixed" gpdf (with the offensive code commented out) is available here[4] (the binary for i386, provided there, is compiled w/o optimizations and debugging symbols are unstripped) Related bugs in other locations (neither of which is marked as fixed): https://bugs.freedesktop.org/show_bug.cgi?id=1043 http://bugs.gentoo.org/show_bug.cgi?id=31982 [1]. http://www.kde-look.org/content/show.php?content=18214 [2]. http://mif.vu.lt/~mova3971/xf/watch [3]. http://mif.vu.lt/~mova3971/xf/memleak.c [4]. http://mif.vu.lt/~mova3971/xf/gpdf
pgpvX8xz0JQUj.pgp
Description: PGP signature