ctdb debug vasprintf memory overwrite in ib

Peter Somogyi psomogyi at gamax.hu
Fri Apr 20 11:09:49 GMT 2007


Hi Volker,

Accidentally I've run into a memory overwrite problem with your debug code 
(ctdb/lib/util/debug.c/do_debug).

# gdb bin/ibwrapper_test #-i 1 -d 10.0.0.2:8001 -t 0 -n 1000
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i586-suse-linux"...Using host libthread_db 
library "/lib/libthread_db.so.1".

(gdb) break ibwrapper.c:559
Breakpoint 1 at 0x805697b: file ib/ibwrapper.c, line 559.
(gdb) run -i 1 -d 10.0.0.2:8001 -t 0 -n 1000
Starting program: /root/psomogyi/ctdb/bin/ibwrapper_test -i 1 -d 
10.0.0.2:8001 -t 0 -n 1000
[Thread debugging using libthread_db enabled]
[New Thread -1209997120 (LWP 9731)]
[Switching to Thread -1209997120 (LWP 9731)]

Breakpoint 1, ibw_event_handler_cm (ev=0x80691c8, fde=0x8069868, flags=1, 
private_data=0x8069258) at ib/ibwrapper.c:559
559             if (event!=NULL && (rc=rdma_ack_cm_event(event))) {
(gdb) print cma_id->context
$1 = (void *) 0x806b788
(gdb) next
563             DEBUG(0, ("cm event handler: %s", ibw_lasterr));
(gdb) print cma_id->context
$2 = (void *) 0x806b788
(gdb) next
1177065484.603498 [9731]: cm event handler: RDMA_CM_EVENT_REJECTED, error 8
565             if (cma_id!=pctx->cm_id) {
(gdb) print cma_id->context
$3 = (void *) 0x6e616820

More precisely, after the call vasprintf gets the memory overwritten (shows me 
gdb by stepping).
When I change vasprintf usage to vsprintf/vsnprintf with fixed buffer then it 
runs fine. Also runs fine when I comment its line.

BTW. man says vasprintf is a GNU extension, not in POSIX or C. It tells 
something also about #define _GNU_SOURCE.

I'm still not aware of *why* this overwrite happens, but on my system somehow 
it occures. (vasprintf returns 50 which is ok, so we don't have failure.)

(glibc version is 2.4-31.2 on my SLES10)

Picking another vasprintf implementation like this solves my problem:

int vasprintf(char **ptr, const char *format, va_list ap)
{
    int ret;
    va_list tmp_ap;

    va_copy(tmp_ap, ap);
    ret = vsnprintf(NULL, 0, format, tmp_ap);
    if (ret <= 0) return ret;

    (*ptr) = (char *)malloc(ret+1);
    if (!*ptr) return -1;
    ret = vsnprintf(*ptr, ret+1, format, ap);

    return ret;
}
(code is from jerry at samba.org 
http://lists.samba.org/archive/samba-technical/2001-October/016595.html)

Do you agree changing do_debug this way?

-- 
Peter Somogyi
Gamax Kft
Bartok Bela ut 15/D
H-1114, Budapest, Hungary
e-mail: psomogyi at gamax.hu


More information about the samba-technical mailing list