aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-17 16:48:47 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-17 16:48:47 +0000
commit9f73bdd388dd74512a00a0072b29e85722649157 (patch)
tree4480c9f10ea06c275ca5815cd8465c6713e73343 /main
parent031da201bb6d063f89d3f099171b0b86c5eb9093 (diff)
Merged revisions 114208 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r114208 | mmichelson | 2008-04-17 11:40:12 -0500 (Thu, 17 Apr 2008) | 20 lines Merged revisions 114207 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r114207 | mmichelson | 2008-04-17 11:28:03 -0500 (Thu, 17 Apr 2008) | 12 lines It was possible for a reference to a frame which was part of a freed DSP to still be referenced, leading to memory corruption and eventual crashes. This code change ensures that the dsp is freed when we are finished with the frame. This change is very similar to a change Russell made with translators back a month or so ago. (closes issue #11999) Reported by: destiny6628 Patches: 11999.patch uploaded by putnopvut (license 60) Tested by: destiny6628, victoryure ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@114210 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/dsp.c31
-rw-r--r--main/frame.c4
2 files changed, 35 insertions, 0 deletions
diff --git a/main/dsp.c b/main/dsp.c
index 6945464d4..f24030ebb 100644
--- a/main/dsp.c
+++ b/main/dsp.c
@@ -1241,6 +1241,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = AST_FRAME_NULL;
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
@@ -1250,6 +1251,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
dsp->f.subclass = AST_CONTROL_BUSY;
ast_frfree(af);
ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
if (((dsp->features & DSP_FEATURE_DTMF_DETECT) || (dsp->features & DSP_FEATURE_FAX_DETECT))) {
@@ -1271,6 +1273,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
} else {
@@ -1297,6 +1300,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
ast_queue_frame(chan, af);
ast_frfree(af);
}
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
} else {
memset(&dsp->f, 0, sizeof(dsp->f));
@@ -1314,6 +1318,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
}
@@ -1331,6 +1336,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
return &dsp->f;
}
}
@@ -1403,6 +1409,17 @@ void ast_dsp_set_features(struct ast_dsp *dsp, int features)
void ast_dsp_free(struct ast_dsp *dsp)
{
+ if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) {
+ /* If this flag is still set, that means that the dsp's destruction
+ * been torn down, while we still have a frame out there being used.
+ * When ast_frfree() gets called on that frame, this ast_trans_pvt
+ * will get destroyed, too. */
+
+ /* Set the magic flag to destroy the dsp when the frame is freed */
+ dsp->freqcount = -1;
+
+ return;
+ }
ast_free(dsp);
}
@@ -1516,3 +1533,17 @@ int ast_dsp_get_tcount(struct ast_dsp *dsp)
{
return dsp->tcount;
}
+
+void ast_dsp_frame_freed(struct ast_frame *fr)
+{
+ struct ast_dsp *dsp;
+
+ ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
+
+ dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f));
+
+ if (dsp->freqcount != -1)
+ return;
+
+ ast_dsp_free(dsp);
+}
diff --git a/main/frame.c b/main/frame.c
index 07ce936f2..dc471eebe 100644
--- a/main/frame.c
+++ b/main/frame.c
@@ -37,6 +37,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/threadstorage.h"
#include "asterisk/linkedlists.h"
#include "asterisk/translate.h"
+#include "asterisk/dsp.h"
#ifdef TRACE_FRAMES
static int headers;
@@ -308,6 +309,8 @@ void ast_frame_free(struct ast_frame *fr, int cache)
{
if (ast_test_flag(fr, AST_FRFLAG_FROM_TRANSLATOR))
ast_translate_frame_freed(fr);
+ else if (ast_test_flag(fr, AST_FRFLAG_FROM_DSP))
+ ast_dsp_frame_freed(fr);
if (!fr->mallocd)
return;
@@ -357,6 +360,7 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr)
void *newdata;
ast_clear_flag(fr, AST_FRFLAG_FROM_TRANSLATOR);
+ ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
if (!(fr->mallocd & AST_MALLOCD_HDR)) {
/* Allocate a new header if needed */