[lttng-dev] UST segfault: memcpy too big

Hollis Blanchard hollis_blanchard at mentor.com
Mon Oct 8 19:14:27 EDT 2012

I seem to have hit a little problem with a "hello world" test app and 
lttng-ust 2.0.3. lttng-ust.git seems to be affected as well. Basically, 
I created a single UST tracepoint, but as soon as I run "lttng 
enable-event -u -a", my app segfaults. The problem seems to be that when 
creating the event to pass to ltt_event_create(), we try to memcpy the 
full 256 bytes of name. However, the name might be shorter, and if we 
get unlucky it falls within 256 bytes of the segment boundary...

Completely untested patch, using strncpy instead of memcpy:

--- liblttng-ust/ltt-events.c.orig      2012-10-08 16:02:16.421494319 -0700
+++ liblttng-ust/ltt-events.c   2012-10-08 16:03:24.770293756 -0700
@@ -248,9 +248,10 @@ int pending_probe_fix_events(const struc

                                 memcpy(&event_param, &sw->event_param,
-                               memcpy(event_param.name,
+                               stncpy(event_param.name,
+                               event_param.name[sizeof(event_param.name)-1] = '\0';
                                 /* create event */
                                 ret = ltt_event_create(sw->chan,
                                         &event_param, NULL,

In addition to not testing this patch, I haven't audited other callers 
to see if it's a pattern that also needs to be fixed elsewhere.

Debug info:

Program received signal SIGSEGV, Segmentation fault.
0x4da8d8d4 in memcpy () from /home/hollisb/work/panda-mel-sysroot/lib/libc.so.6
(gdb) bt
#0  0x4da8d8d4 in memcpy () from /home/hollisb/work/panda-mel-sysroot/lib/libc.so.6
#1  0x4007eacc in pending_probe_fix_events (desc=0x8bec) at ltt-events.c:251
#2  0x4007b980 in ltt_probe_register (desc=0x11164) at ltt-probes.c:119
#3  0x0000886c in __lttng_events_init__lighttpd_connection ()
     at /home/hollisb/work/panda-mel-sysroot/usr/include/lttng/ust-tracepoint-event.h:554
#4  0x00008b84 in __libc_csu_init (argc=0x1, argv=0xbe8cfe24, envp=0xbe8cfe2c) at elf-init.c:124
#5  0x4da1f848 in __libc_start_main (main=0xbe8cfe24, argc=0x4db4a000, ubp_av=0x4da1f848,
     init=0x8ad0 <__libc_csu_init>, fini=0x8b98 <__libc_csu_fini>, rtld_fini=0x4d9e8018 <_dl_fini>,
     stack_end=0xbe8cfe24) at libc-start.c:185
#6  0x00008968 in _start ()
(gdb) up
#1  0x4007eacc in pending_probe_fix_events (desc=0x8bec) at ltt-events.c:251
(gdb) list
247					int ret;
249					memcpy(&event_param, &sw->event_param,
250							sizeof(event_param));
251					memcpy(event_param.name,
252						desc->name,
253						sizeof(event_param.name));
254					/* create event */
255					ret = ltt_event_create(sw->chan,
256						&event_param, NULL,
(gdb) p desc->name
$10 = 0x8f10 "lighttpd_connection:create"
(gdb) p sizeof(event_param.name)
$11 = 0x100
(gdb) x/64 desc->name
0x8f10:	0x6867696c	0x64707474	0x6e6f635f	0x7463656e
0x8f20:	0x3a6e6f69	0x61657263	0x6574	0x2c746e69
0x8f30:	0x6e6f6320	0x0	0x6867696c	0x64707474
0x8f40:	0x6e6f635f	0x7463656e	0x6e6f69	0x727470
0x8f50 <__tp_strtab_lighttpd_connection___create>:	0x6867696c	0x64707474	0x6e6f635f	0x7463656e
0x8f60 <__tp_strtab_lighttpd_connection___create+16>:	0x3a6e6f69	0x61657263	0x6574	0x8101b108
0x8f70:	0x8400b0b0	0x0	0x8101b108	0x8400b0b0
0x8f80:	0x0	0x8101b108	0x8400b0b0	0x0
0x8f90:	0x7ffff740	0x7fffffe4	0x7ffff76c	0x80a8b0b0
0x8fa0:	0x7ffff7ec	0x80b0b0b0	0x7ffff7f0	0x80a8b0b0
0x8fb0:	0x7ffff8b0	0x7fffffd0	0x7ffff8e4	0x80b108af
0x8fc0:	0x7ffff97c	0x1	0x7ffff9d4	0x80b0b0b0
0x8fd0:	0x7ffff9e8	0x7fffff98	0x7ffffa10	0x8015aab0
0x8fe0:	0x7ffffaf0	0x80aeb0b0	0x7ffffbb0	0x80b0b0b0
0x8ff0:	0x7ffffbac	0x1	0x0	0x0
0x9000:	Cannot access memory at address 0x9000

Uh oh...

% readelf -l tracetest-arm

Elf file type is EXEC (Executable file)
Entry point 0x893c
There are 8 program headers, starting at offset 52

Program Headers:
   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
   EXIDX          0x000f90 0x00008f90 0x00008f90 0x00068 0x00068 R   0x4
   PHDR           0x000034 0x00008034 0x00008034 0x00100 0x00100 R E 0x4
   INTERP         0x000134 0x00008134 0x00008134 0x00013 0x00013 R   0x1
       [Requesting program interpreter: /lib/ld-linux.so.3]
   LOAD           0x000000 0x00008000 0x00008000 0x00ffc 0x00ffc R E 0x8000
   LOAD           0x001000 0x00011000 0x00011000 0x001cc 0x001f8 RW  0x8000
   DYNAMIC        0x00101c 0x0001101c 0x0001101c 0x00100 0x00100 RW  0x4
   NOTE           0x000148 0x00008148 0x00008148 0x00020 0x00020 R   0x4
   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

Note the hole between those two LOAD segments. desc->name landed very 
close to the end of the first. I got lucky on x86, where (at least with 
my toolchain) the next segment happens to land closer:

   LOAD           0x000000 0x08048000 0x08048000 0x00f98 0x00f98 R E 0x1000
   LOAD           0x001000 0x08049000 0x08049000 0x00204 0x00248 RW  0x1000

Hollis Blanchard
Product Owner, Sourcery Analyzer <http://go.mentor.com/sourceryanalyzer>
Mentor Graphics, Embedded Systems Division

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lttng.org/pipermail/lttng-dev/attachments/20121008/5d7c16ee/attachment.html>

More information about the lttng-dev mailing list