summaryrefslogtreecommitdiff
path: root/main/dsp.c
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2008-04-17 16:40:12 +0000
committerMark Michelson <mmichelson@digium.com>2008-04-17 16:40:12 +0000
commitae52cd4a7648e67443a45b36c09ba76919a803a4 (patch)
tree0d0576e91f0444125f19ee1f3b0e55d74e125c5a /main/dsp.c
parent83c674bf96ca0bf4a29c675fd901eb98700a8e92 (diff)
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: https://origsvn.digium.com/svn/asterisk/trunk@114208 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/dsp.c')
-rw-r--r--main/dsp.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/main/dsp.c b/main/dsp.c
index f2d47df59..935bcb0bf 100644
--- a/main/dsp.c
+++ b/main/dsp.c
@@ -388,6 +388,7 @@ struct ast_dsp {
digit_detect_state_t digit_state;
tone_detect_state_t cng_tone_state;
tone_detect_state_t ced_tone_state;
+ int destroy;
};
static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
@@ -1310,6 +1311,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)) {
@@ -1319,6 +1321,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;
}
@@ -1424,6 +1427,7 @@ done:
if (chan)
ast_queue_frame(chan, af);
ast_frfree(af);
+ ast_set_flag(outf, AST_FRFLAG_FROM_DSP);
return outf;
} else {
return af;
@@ -1474,6 +1478,16 @@ 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. */
+
+ dsp->destroy = 1;
+
+ return;
+ }
ast_free(dsp);
}
@@ -1632,3 +1646,16 @@ int ast_dsp_reload(void)
return _dsp_init(1);
}
+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->destroy)
+ return;
+
+ ast_dsp_free(dsp);
+}