[PATCH] Don't crash when frestoring a truncated fdump string
Repolho <[email protected]>
| Newsgroups | gmane.comp.window-managers.ratpoison.devel |
|---|---|
| Message-ID | <20130809155203.GA28530@darch> |
If actions.c:frestore() is passed a truncated fdump string which is missing the value in the last of its key-value pairs, it forwards the token in question to frame.c:frame_read(), which then calls the macro frame.c:read_slot() on that key-value pair that is missing the value, and then, finally, strtol() gets called on a NULL pointer, resulting in the following crash (from gdb, edited for brevity): Program received signal SIGSEGV, Segmentation fault. 0x00007f4defc20f26 in ____strtoll_l_internal () from /usr/lib/libc.so.6 #0 0x00007f4defc20f26 in ____strtoll_l_internal () from /usr/lib/libc.so.6 #1 0x0000000000418d38 in frame_read (str=0x9ab450 "(frame :number 0 :x", screen=0x9796a0) at frame.c:229 #2 0x00000000004100fd in frestore (data=0x9b48a0 "(frame :number 0 :x", s=0x9796a0) at actions.c:4943 #3 0x00000000004104de in cmd_frestore (interactively=0, args=0x9ab470) at actions.c:5016 To reproduce, run: $ ratpoison -c 'frestore (frame :number 0 :x' or just using any fdump string after removing the last value. Since frestore() handles truncated fdump strings that are missing one or more key-value pairs by using default values instead, the attached patch also fixes the issue by returning a default value of zero when only the key is present but its value is missing. It was generated over the latest git, v1.4.6-56-gdf842f3. _______________________________________________ Ratpoison-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/ratpoison-devel
frame_read_crash.patch
(text/x-diff, 446 B)
diff --git a/src/frame.c b/src/frame.c
index c42e2ab..5d18218 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -190,7 +190,7 @@ frame_dump (rp_frame *frame, rp_screen *screen)
}
/* Used only by frame_read */
-#define read_slot(x) do { tmp = strtok_ws (NULL); x = strtol(tmp,NULL,10); } while(0)
+#define read_slot(x) do { tmp = strtok_ws (NULL); x = tmp?strtol(tmp,NULL,10):0; } while(0)
rp_frame *
frame_read (char *str, rp_screen *screen)