]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_rtp_asterisk: Resolve 2 discrete memory leaks in DTLS 68/268/4
authorSteve Davies <steve@one47.co.uk>
Tue, 28 Apr 2015 10:38:30 +0000 (11:38 +0100)
committerJoshua Colp <jcolp@digium.com>
Tue, 28 Apr 2015 11:57:34 +0000 (06:57 -0500)
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

main/rtp_engine.c
res/res_rtp_asterisk.c

index 70292ce3467d572d5a950130579ff6d453c4f178..870ccc45ff08160506d4e77ff53a1d13f04b0b8f 100644 (file)
@@ -2162,6 +2162,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;
index 80bc756254d32ae2e5435aa2223c3a8018e9c550..7389f9eae33a6aff29816243a50b61f97e1fcd20 100644 (file)
@@ -1852,6 +1852,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) {
@@ -1966,16 +1967,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