Browse Source

Replaced sprintf by snprintf for cdrbuffer

Avoid buffer overflows.
Also make cdrbuffend -= 1; append spaces to the TRUNCATED message because
syslog trims the output to 8205 chars on a line for big log buffers.
pull/176/head
Frederic-Philippe Metz 10 years ago
committed by smititelu
parent
commit
10f6e51b72
3 changed files with 117 additions and 104 deletions
  1. +107
    -94
      daemon/call.c
  2. +10
    -0
      daemon/call.h
  3. +0
    -10
      daemon/cli.c

+ 107
- 94
daemon/call.c View File

@ -2795,6 +2795,8 @@ struct timeval add_ongoing_calls_dur_in_interval(struct callmaster *m,
return res; return res;
} }
#define CDRBUFREMAINDER cdrbufend-cdrbufcur
/* called lock-free, but must hold a reference to the call */ /* called lock-free, but must hold a reference to the call */
void call_destroy(struct call *c) { void call_destroy(struct call *c) {
struct callmaster *m = c->callmaster; struct callmaster *m = c->callmaster;
@ -2810,7 +2812,9 @@ void call_destroy(struct call *c) {
static const int CDRBUFLENGTH = 4096*2; static const int CDRBUFLENGTH = 4096*2;
char cdrbuffer[CDRBUFLENGTH]; char cdrbuffer[CDRBUFLENGTH];
char* cdrbufcur = cdrbuffer; char* cdrbufcur = cdrbuffer;
char* cdrbufend = cdrbuffer+CDRBUFLENGTH-1;
int cdrlinecnt = 0; int cdrlinecnt = 0;
int printlen=0;
int found = 0; int found = 0;
const struct rtp_payload_type *rtp_pt; const struct rtp_payload_type *rtp_pt;
@ -2842,10 +2846,14 @@ void call_destroy(struct call *c) {
/* CDRs and statistics */ /* CDRs and statistics */
if (_log_facility_cdr) { if (_log_facility_cdr) {
cdrbufcur += sprintf(cdrbufcur,"ci=%s, ",c->callid.s);
cdrbufcur += sprintf(cdrbufcur,"created_from=%s, ", c->created_from);
cdrbufcur += sprintf(cdrbufcur,"last_signal=%llu, ", (unsigned long long)c->last_signal);
cdrbufcur += sprintf(cdrbufcur,"tos=%u, ", (unsigned int)c->tos);
printlen = snprintf(cdrbufcur,CDRBUFREMAINDER,"ci=%s, ",c->callid.s);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
printlen = snprintf(cdrbufcur,CDRBUFREMAINDER,"created_from=%s, ", c->created_from);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
printlen = snprintf(cdrbufcur,CDRBUFREMAINDER,"last_signal=%llu, ", (unsigned long long)c->last_signal);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
printlen = snprintf(cdrbufcur,CDRBUFREMAINDER,"tos=%u, ", (unsigned int)c->tos);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
} }
for (l = c->monologues; l; l = l->next) { for (l = c->monologues; l; l = l->next) {
@ -2859,20 +2867,22 @@ void call_destroy(struct call *c) {
timeval_subtract(&tim_result_duration,&ml->terminated,&ml->started); timeval_subtract(&tim_result_duration,&ml->terminated,&ml->started);
if (_log_facility_cdr) { if (_log_facility_cdr) {
cdrbufcur += sprintf(cdrbufcur, "ml%i_start_time=%ld.%06lu, "
"ml%i_end_time=%ld.%06ld, "
"ml%i_duration=%ld.%06ld, "
"ml%i_termination=%s, "
"ml%i_local_tag=%s, "
"ml%i_local_tag_type=%s, "
"ml%i_remote_tag=%s, ",
cdrlinecnt, ml->started.tv_sec, ml->started.tv_usec,
cdrlinecnt, ml->terminated.tv_sec, ml->terminated.tv_usec,
cdrlinecnt, tim_result_duration.tv_sec, tim_result_duration.tv_usec,
cdrlinecnt, get_term_reason_text(ml->term_reason),
cdrlinecnt, ml->tag.s,
cdrlinecnt, get_tag_type_text(ml->tagtype),
cdrlinecnt, ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)");
printlen = snprintf(cdrbufcur, CDRBUFREMAINDER,
"ml%i_start_time=%ld.%06lu, "
"ml%i_end_time=%ld.%06ld, "
"ml%i_duration=%ld.%06ld, "
"ml%i_termination=%s, "
"ml%i_local_tag=%s, "
"ml%i_local_tag_type=%s, "
"ml%i_remote_tag=%s, ",
cdrlinecnt, ml->started.tv_sec, ml->started.tv_usec,
cdrlinecnt, ml->terminated.tv_sec, ml->terminated.tv_usec,
cdrlinecnt, tim_result_duration.tv_sec, tim_result_duration.tv_usec,
cdrlinecnt, get_term_reason_text(ml->term_reason),
cdrlinecnt, ml->tag.s,
cdrlinecnt, get_tag_type_text(ml->tagtype),
cdrlinecnt, ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)");
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
} }
ilog(LOG_INFO, "--- Tag '"STR_FORMAT"', created " ilog(LOG_INFO, "--- Tag '"STR_FORMAT"', created "
@ -2905,10 +2915,11 @@ void call_destroy(struct call *c) {
/* add PayloadType(codec) info in CDR logging */ /* add PayloadType(codec) info in CDR logging */
if (_log_facility_cdr && rtp_pt) { if (_log_facility_cdr && rtp_pt) {
cdrbufcur += sprintf(cdrbufcur,
"payload_type=%u, ", rtp_pt->payload_type);
printlen = snprintf(cdrbufcur, CDRBUFREMAINDER, "payload_type=%u, ", rtp_pt->payload_type);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
} else if (_log_facility_cdr && !rtp_pt) { } else if (_log_facility_cdr && !rtp_pt) {
cdrbufcur += sprintf(cdrbufcur, "payload_type=unknown, ");
printlen = snprintf(cdrbufcur, CDRBUFREMAINDER, "payload_type=unknown, ");
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
} }
for (o = md->streams.head; o; o = o->next) { for (o = md->streams.head; o; o = o->next) {
@ -2923,82 +2934,84 @@ void call_destroy(struct call *c) {
const char* protocol = (!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) ? "rtcp" : "rtp"; const char* protocol = (!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) ? "rtcp" : "rtp";
if(!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) { if(!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) {
cdrbufcur += sprintf(cdrbufcur,
"ml%i_midx%u_%s_endpoint_ip=%s, "
"ml%i_midx%u_%s_endpoint_port=%u, "
"ml%i_midx%u_%s_local_relay_port=%u, "
"ml%i_midx%u_%s_relayed_packets="UINT64F", "
"ml%i_midx%u_%s_relayed_bytes="UINT64F", "
"ml%i_midx%u_%s_relayed_errors="UINT64F", "
"ml%i_midx%u_%s_last_packet="UINT64F", "
"ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", ",
cdrlinecnt, md->index, protocol, addr,
cdrlinecnt, md->index, protocol, ps->endpoint.port,
cdrlinecnt, md->index, protocol, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.packets),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.bytes),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.errors),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->last_packet),
cdrlinecnt, md->index, protocol,
ps->stats.in_tos_tclass);
printlen = snprintf(cdrbufcur, CDRBUFREMAINDER,
"ml%i_midx%u_%s_endpoint_ip=%s, "
"ml%i_midx%u_%s_endpoint_port=%u, "
"ml%i_midx%u_%s_local_relay_port=%u, "
"ml%i_midx%u_%s_relayed_packets="UINT64F", "
"ml%i_midx%u_%s_relayed_bytes="UINT64F", "
"ml%i_midx%u_%s_relayed_errors="UINT64F", "
"ml%i_midx%u_%s_last_packet="UINT64F", "
"ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", ",
cdrlinecnt, md->index, protocol, addr,
cdrlinecnt, md->index, protocol, ps->endpoint.port,
cdrlinecnt, md->index, protocol, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.packets),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.bytes),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.errors),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->last_packet),
cdrlinecnt, md->index, protocol,
ps->stats.in_tos_tclass);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
} else { } else {
#if (RE_HAS_MEASUREDELAY) #if (RE_HAS_MEASUREDELAY)
cdrbufcur += sprintf(cdrbufcur,
"ml%i_midx%u_%s_endpoint_ip=%s, "
"ml%i_midx%u_%s_endpoint_port=%u, "
"ml%i_midx%u_%s_local_relay_port=%u, "
"ml%i_midx%u_%s_relayed_packets="UINT64F", "
"ml%i_midx%u_%s_relayed_bytes="UINT64F", "
"ml%i_midx%u_%s_relayed_errors="UINT64F", "
"ml%i_midx%u_%s_last_packet="UINT64F", "
"ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", "
"ml%i_midx%u_%s_delay_min=%.9f, "
"ml%i_midx%u_%s_delay_avg=%.9f, "
"ml%i_midx%u_%s_delay_max=%.9f, ",
cdrlinecnt, md->index, protocol, addr,
cdrlinecnt, md->index, protocol, ps->endpoint.port,
cdrlinecnt, md->index, protocol, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.packets),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.bytes),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.errors),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->last_packet),
cdrlinecnt, md->index, protocol,
ps->stats.in_tos_tclass,
cdrlinecnt, md->index, protocol, (double) ps->stats.delay_min / 1000000,
cdrlinecnt, md->index, protocol, (double) ps->stats.delay_avg / 1000000,
cdrlinecnt, md->index, protocol, (double) ps->stats.delay_max / 1000000);
printlen = snprintf(cdrbufcur, CDRBUFREMAINDER,
"ml%i_midx%u_%s_endpoint_ip=%s, "
"ml%i_midx%u_%s_endpoint_port=%u, "
"ml%i_midx%u_%s_local_relay_port=%u, "
"ml%i_midx%u_%s_relayed_packets="UINT64F", "
"ml%i_midx%u_%s_relayed_bytes="UINT64F", "
"ml%i_midx%u_%s_relayed_errors="UINT64F", "
"ml%i_midx%u_%s_last_packet="UINT64F", "
"ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", "
"ml%i_midx%u_%s_delay_min=%.9f, "
"ml%i_midx%u_%s_delay_avg=%.9f, "
"ml%i_midx%u_%s_delay_max=%.9f, ",
cdrlinecnt, md->index, protocol, addr,
cdrlinecnt, md->index, protocol, ps->endpoint.port,
cdrlinecnt, md->index, protocol, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.packets),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.bytes),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.errors),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->last_packet),
cdrlinecnt, md->index, protocol,
ps->stats.in_tos_tclass,
cdrlinecnt, md->index, protocol, (double) ps->stats.delay_min / 1000000,
cdrlinecnt, md->index, protocol, (double) ps->stats.delay_avg / 1000000,
cdrlinecnt, md->index, protocol, (double) ps->stats.delay_max / 1000000);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
#else #else
cdrbufcur += sprintf(cdrbufcur,
"ml%i_midx%u_%s_endpoint_ip=%s, "
"ml%i_midx%u_%s_endpoint_port=%u, "
"ml%i_midx%u_%s_local_relay_port=%u, "
"ml%i_midx%u_%s_relayed_packets="UINT64F", "
"ml%i_midx%u_%s_relayed_bytes="UINT64F", "
"ml%i_midx%u_%s_relayed_errors="UINT64F", "
"ml%i_midx%u_%s_last_packet="UINT64F", "
"ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", ",
cdrlinecnt, md->index, protocol, addr,
cdrlinecnt, md->index, protocol, ps->endpoint.port,
cdrlinecnt, md->index, protocol, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.packets),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.bytes),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.errors),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->last_packet),
cdrlinecnt, md->index, protocol,
ps->stats.in_tos_tclass);
printlen = snprintf(cdrbufcur, CDRBUFREMAINDER,
"ml%i_midx%u_%s_endpoint_ip=%s, "
"ml%i_midx%u_%s_endpoint_port=%u, "
"ml%i_midx%u_%s_local_relay_port=%u, "
"ml%i_midx%u_%s_relayed_packets="UINT64F", "
"ml%i_midx%u_%s_relayed_bytes="UINT64F", "
"ml%i_midx%u_%s_relayed_errors="UINT64F", "
"ml%i_midx%u_%s_last_packet="UINT64F", "
"ml%i_midx%u_%s_in_tos_tclass=%" PRIu8 ", ",
cdrlinecnt, md->index, protocol, addr,
cdrlinecnt, md->index, protocol, ps->endpoint.port,
cdrlinecnt, md->index, protocol, (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.packets),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.bytes),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->stats.errors),
cdrlinecnt, md->index, protocol,
atomic64_get(&ps->last_packet),
cdrlinecnt, md->index, protocol,
ps->stats.in_tos_tclass);
ADJUSTLEN(printlen,cdrbufend,cdrbufcur);
#endif #endif
} }
} }


+ 10
- 0
daemon/call.h View File

@ -18,6 +18,16 @@
#include "control_ng.h" #include "control_ng.h"
#include "aux.h" #include "aux.h"
#define TRUNCATED " ... Output truncated. Increase Output Buffer ... \n"
#define truncate_output(x) strcpy(x - strlen(TRUNCATED) - 1, TRUNCATED)
#define ADJUSTLEN(printlen,outbufend,replybuffer) do { \
replybuffer += (printlen>=outbufend-replybuffer)?outbufend-replybuffer:printlen; \
if (replybuffer == outbufend) \
truncate_output(replybuffer); \
} while (0);
enum termination_reason { enum termination_reason {
UNKNOWN=0, UNKNOWN=0,
REGULAR=1, REGULAR=1,


+ 0
- 10
daemon/cli.c View File

@ -16,16 +16,6 @@
#include "rtpengine_config.h" #include "rtpengine_config.h"
static const char* TRUNCATED = " ... Output truncated. Increase Output Buffer ...\n";
#define truncate_output(x) strcpy(x - strlen(TRUNCATED) - 1, TRUNCATED)
#define ADJUSTLEN(printlen,outbuflen,replybuffer) do { \
replybuffer += (printlen>=outbufend-replybuffer)?outbufend-replybuffer:printlen; \
if (replybuffer == outbufend) \
truncate_output(replybuffer); \
} while (0);
static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) { static void cli_incoming_list_totals(char* buffer, int len, struct callmaster* m, char* replybuffer, const char* outbufend) {
int printlen=0; int printlen=0;
struct timeval avg, calls_dur_iv; struct timeval avg, calls_dur_iv;


Loading…
Cancel
Save