Comment 5 for bug 736081

Revision history for this message
Jani Monoses (jani) wrote :

The function that appears to be miscompiled and which is called by the test is in telepathy-glib/debug.c

Building this file alone with -O0 does not lead to crash. Same result if the debug_flag_to_domain() function which is called here, and which is static to the debug.c file is either made non-static, or flagged with __attribute__((noinline)). In both of these cases
this will not be inlined and code generated is correct.

void _tp_log (GLogLevelFlags level,
              TpDebugFlags flag,
              const gchar *format,
              ...)
{
  if ((flag & flags) || level > G_LOG_LEVEL_DEBUG)
    {
      va_list args;
      va_start (args, format);
      g_logv (debug_flag_to_domain (flag), level, format, args);
      va_end (args);
    }

}

The function has 3 arguments, but r2 is overwritten by r0 without being saved first.
So format <= level on the second line of the disassembled code

000000d8 <_tp_log>:
  d8: f240 0300 movw r3, #0
  dc: 4602 mov r2, r0 // THIS APPEARS TO OVERWRITE THE FORMAT ARGUMENT WITH THE LEVEL ARGUMENT
  de: f2c0 0300 movt r3, #0
  e2: 681b ldr r3, [r3, #0]
  e4: 4219 tst r1, r3
  e6: bf0c ite eq
  e8: 2300 moveq r3, #0
  ea: 2301 movne r3, #1
  ec: 2880 cmp r0, #128 ; 0x80
  ee: bfc8 it gt
  f0: f043 0301 orrgt.w r3, r3, #1

gdb backtrace of the crash confirms format is passed down to callees with an invalid value (0x80 = G_LOG_LEVEL_DEBUG)

Program received signal SIGSEGV, Segmentation fault.
__strchrnul (s=<value optimized out>, c_in=<value optimized out>) at strchrnul.c:122
122 strchrnul.c: No such file or directory.
        in strchrnul.c
(gdb) bt
#0 __strchrnul (s=<value optimized out>, c_in=<value optimized out>) at strchrnul.c:122
#1 0x40366dd2 in __find_specmb (s=0xbec1d098, format=0x80 <Address 0x80 out of bounds>, ap=...) at printf-parse.h:99
#2 _IO_vfprintf_internal (s=0xbec1d098, format=0x80 <Address 0x80 out of bounds>, ap=...) at vfprintf.c:1325
#3 0x403d5b56 in __vasprintf_chk (result_ptr=0xbec1d174, flags=1, format=0x80 <Address 0x80 out of bounds>, args=...) at vasprintf_chk.c:68
#4 0x402e3a1a in vasprintf (string=0xbec1d174, format=0x80 <Address 0x80 out of bounds>, args=<value optimized out>) at /usr/include/bits/stdio2.h:199
#5 g_vasprintf (string=0xbec1d174, format=0x80 <Address 0x80 out of bounds>, args=<value optimized out>) at /build/buildd/glib2.0-2.28.4/./glib/gprintf.c:318
#6 0x402c9eca in g_strdup_vprintf (format=<value optimized out>, args=<value optimized out>) at /build/buildd/glib2.0-2.28.4/./glib/gstrfuncs.c:255
#7 0x402ba1f8 in g_logv (log_domain=0x8da0 "tp-glib/accounts", log_level=G_LOG_LEVEL_DEBUG, format=0x80 <Address 0x80 out of bounds>, args1=...) at /build/buildd/glib2.0-2.28.4/./glib/gmessages.c:524
#8 0x00008a2c in _tp_log (level=-1094593012, flag=37, format=0x80 <Address 0x80 out of bounds>) at debug.c:311
#9 0x000088fc in main (argc=<value optimized out>, argv=<value optimized out>) at debug-domain.c:17