From: Steve Davies Date: Tue, 28 Apr 2015 10:38:30 +0000 (+0100) Subject: res_rtp_asterisk: Resolve 2 discrete memory leaks in DTLS X-Git-Tag: 14.0.0-beta1~1027 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fchanges%2F70%2F270%2F4;p=thirdparty%2Fasterisk.git res_rtp_asterisk: Resolve 2 discrete memory leaks in DTLS ao2 ref leak in res_rtp_asterisk.c when a DTLS policy is created. The resources are linked into a table, but the original alloc refs are never released. ast_strdup leak in rtp_engine.c. If ast_rtp_dtls_cfg_copy() is called twice on the same destination struct, a pointer to an alloc'd string is overwritten before the string is free'd. ASTERISK-25022 Reported by: one47 Change-Id: I62a8ceb8679709f6c3769136dc6aa9a68202ff9b --- diff --git a/main/rtp_engine.c b/main/rtp_engine.c index 34e6a9439f..9c9ad4e7b5 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -1659,6 +1659,8 @@ int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name, void ast_rtp_dtls_cfg_copy(const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rtp_dtls_cfg *dst_cfg) { + ast_rtp_dtls_cfg_free(dst_cfg); /* Prevent a double-call leaking memory via ast_strdup */ + dst_cfg->enabled = src_cfg->enabled; dst_cfg->verify = src_cfg->verify; dst_cfg->rekey = src_cfg->rekey; diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 0513c11271..62601dcada 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -1869,6 +1869,7 @@ static int dtls_srtp_setup(struct ast_rtp *rtp, struct ast_srtp *srtp, struct as unsigned char *local_key, *local_salt, *remote_key, *remote_salt; struct ast_srtp_policy *local_policy, *remote_policy = NULL; struct ast_rtp_instance_stats stats = { 0, }; + int res = -1; /* If a fingerprint is present in the SDP make sure that the peer certificate matches it */ if (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_FINGERPRINT) { @@ -1983,16 +1984,17 @@ static int dtls_srtp_setup(struct ast_rtp *rtp, struct ast_srtp *srtp, struct as } } - return 0; + res = 0; error: + /* policy->destroy() called even on success to release local reference to these resources */ res_srtp_policy->destroy(local_policy); if (remote_policy) { res_srtp_policy->destroy(remote_policy); } - return -1; + return res; } #endif