heap buffer underflow in TAG_TYPE_OF(t)
kamalesh-p opened this issue · 0 comments
kamalesh-p commented
ISSUE:
when using mod_sofia with Address Sanitizer causes a stack-buffer-underflow error
ERROR: AddressSanitizer: stack-buffer-underflow
READ of size 8 at 0x7f3bfcdc0420 thread T14
#0 t_len sofia-sip/su_tag_inline.h:140
#1 tl_len sofia-sip/libsofia-sip-ua/su/su_taglist.c:250
#2 tl_adup sofia-sip/libsofia-sip-ua/su/su_taglist.c:315
#3 nua_create sofia-sip/libsofia-sip-ua/nua/nua.c:154
#4 sofia_profile_thread_run src/mod/endpoints/mod_sofia/sofia.c:3220
This frame has 1 object(s):
[32, 88) 'ta'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions are supported)
TEMPORARY FIX:
I added the below code to temporarily avoid this error
#if SU_HAVE_TAGSTACK
/* All arguments are saved into stack (left-to-right) */
#define ta_start(ta, t, v) \
do { \
tag_type_t ta_start__tag = (t); tag_value_t ta_start__value = (v); \
va_start((ta).ap, (v)); \
while ((ta_start__tag) == tag_next && (ta_start__value) != 0) { \
ta_start__tag = ((tagi_t *)ta_start__value)->t_tag; \
if (ta_start__tag == tag_null || ta_start__tag == NULL) \
break; \
if (ta_start__tag == tag_next) { \
ta_start__value = ((tagi_t *)ta_start__value)->t_value; } \
else { \
ta_start__tag = tag_next; \
break; \
} \
} \
(ta).tl->t_tag = ta_start__tag; (ta).tl->t_value = ta_start__value; \
if (ta_start__tag != NULL && \
ta_start__tag != tag_null && \
ta_start__tag != tag_next) { \
(ta).tl[1].t_tag = 0; \ //EDITED_BY_KAMALESH
(ta).tl[1].t_value = (tag_value_t)(&(v) + 1); \
} else { \
(ta).tl[1].t_tag = 0; (ta).tl[1].t_value = (tag_value_t)0; \
} \
} while(0)
#else
/* Tagged arguments are in registers - copy all of them. */
#define ta_start(ta, t, v) \
do { \
tag_type_t ta_start__tag = (t); tag_value_t ta_start__value = (v); \
va_start((ta).ap, (v)); \
while ((ta_start__tag) == tag_next && (ta_start__value) != 0) { \
ta_start__tag = ((tagi_t *)ta_start__value)->t_tag; \
if (ta_start__tag == tag_null || ta_start__tag == NULL) \
break; \
if (ta_start__tag == tag_next) { \
ta_start__value = ((tagi_t *)ta_start__value)->t_value; \
} else { \
ta_start__tag = tag_next; \
break; \
} \
} \
(ta).tl->t_tag = ta_start__tag; (ta).tl->t_value = ta_start__value; \
if (ta_start__tag != NULL && \
ta_start__tag != tag_null && \
ta_start__tag != tag_next) { \
va_list ta_start__ap; \
su_va_copy(ta_start__ap, (ta).ap); \
(ta).tl[1].t_tag = 0; \ //EDITED_BY_KAMALESH
(ta).tl[1].t_value = (tag_value_t)tl_vlist(ta_start__ap); \
va_end(ta_start__ap); \
} else { \
(ta).tl[1].t_tag = 0; (ta).tl[1].t_value = (tag_value_t)0; \ //EDITED_BY_KAMALESH
} \
} while(0)
#endif