summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorCorey Farrell <git@cfware.com>2014-11-17 16:00:54 +0000
committerCorey Farrell <git@cfware.com>2014-11-17 16:00:54 +0000
commite8286df19c1a5982d80236a1e308ca336cdb7125 (patch)
treeabf4b6512ad61a98fef63bddb6deaa75eca0ced9 /channels
parent45f4fe6f1c5891ba4c424abec27d085959edf0b4 (diff)
chan_sip: Fix theoretical leak of p->refer.
If transmit_refer is called when p->refer is already allocated, it leaks the previous allocation. Updated code to always free previous allocation during a new allocation. Also instead of checking if we have a previous allocation, always create a clean record. ASTERISK-15242 #close Reported by: David Woolley Review: https://reviewboard.asterisk.org/r/4160/ ........ Merged revisions 428117 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 428118 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@428119 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 35f89cc50..fba7fd84d 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1257,6 +1257,7 @@ static int dialog_find_multiple(void *obj, void *arg, int flags);
static struct ast_channel *sip_pvt_lock_full(struct sip_pvt *pvt);
/* static int sip_addrcmp(char *name, struct sockaddr_in *sin); Support for peer matching */
static int sip_refer_alloc(struct sip_pvt *p);
+static void sip_refer_destroy(struct sip_pvt *p);
static int sip_notify_alloc(struct sip_pvt *p);
static int do_magic_pickup(struct ast_channel *channel, const char *extension, const char *context);
static void set_peer_nat(const struct sip_pvt *p, struct sip_peer *peer);
@@ -6476,11 +6477,7 @@ void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist)
ast_udptl_destroy(p->udptl);
p->udptl = NULL;
}
- if (p->refer) {
- ast_string_field_free_memory(p->refer);
- ast_free(p->refer);
- p->refer = NULL;
- }
+ sip_refer_destroy(p);
sip_route_clear(&p->route);
deinit_req(&p->initreq);
@@ -15555,10 +15552,21 @@ static int transmit_message(struct sip_pvt *p, int init, int auth)
/*! \brief Allocate SIP refer structure */
static int sip_refer_alloc(struct sip_pvt *p)
{
+ sip_refer_destroy(p);
p->refer = ast_calloc_with_stringfields(1, struct sip_refer, 512);
return p->refer ? 1 : 0;
}
+/*! \brief Destroy SIP refer structure */
+static void sip_refer_destroy(struct sip_pvt *p)
+{
+ if (p->refer) {
+ ast_string_field_free_memory(p->refer);
+ ast_free(p->refer);
+ p->refer = NULL;
+ }
+}
+
/*! \brief Allocate SIP refer structure */
static int sip_notify_alloc(struct sip_pvt *p)
{
@@ -18114,8 +18122,9 @@ static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
struct sip_refer *refer = NULL;
const char *transfer_context = NULL;
- if (!p->refer && !sip_refer_alloc(p))
+ if (!sip_refer_alloc(p)) {
return -1;
+ }
refer = p->refer;
@@ -25233,7 +25242,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
replace_id = ast_strdupa(p_replaces);
ast_uri_decode(replace_id, ast_uri_sip_user);
- if (!p->refer && !sip_refer_alloc(p)) {
+ if (!sip_refer_alloc(p)) {
transmit_response_reliable(p, "500 Server Internal Error", req);
append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
@@ -26092,7 +26101,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, uint
}
/* Allocate memory for call transfer data */
- if (!p->refer && !sip_refer_alloc(p)) {
+ if (!sip_refer_alloc(p)) {
transmit_response(p, "500 Internal Server Error", req);
append_history(p, "Xfer", "Refer failed. Memory allocation error.");
return -3;