From 9bc8ac021ee572c33dabb90808dd595cb4856b10 Mon Sep 17 00:00:00 2001 From: David Vossel Date: Thu, 23 Jun 2011 18:16:52 +0000 Subject: [PATCH] Addresses AST-2011-010, remote crash in IAX2 driver Thanks to twilson for identifying the issue and providing the patches. AST-2011-010 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@324627 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 14 +++++++++++++- res/res_features.c | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index b81a511240..1f82e8d821 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -4652,7 +4652,14 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat /* these two cannot be sent, because they require a result */ errno = ENOSYS; return -1; - default: + /* These options are sent to the other side across the network where + * they will be passed to whatever channel is bridged there. Don't + * do anything silly like pass an option that transmits pointers to + * memory on this machine to a remote machine to use */ + case AST_OPTION_TONE_VERIFY: + case AST_OPTION_TDD: + case AST_OPTION_RELAXDTMF: + case AST_OPTION_AUDIO_MODE: { unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); struct chan_iax2_pvt *pvt; @@ -4680,7 +4687,12 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat free(h); return res; } + default: + return -1; } + + /* Just in case someone does a break instead of a return */ + return -1; } static struct ast_frame *iax2_read(struct ast_channel *c) diff --git a/res/res_features.c b/res/res_features.c index 6585225303..fa73dcdef3 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -2381,10 +2381,19 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast break; case AST_CONTROL_OPTION: aoh = f->data; - /* Forward option Requests */ + /* Forward option Requests, but only ones we know are safe + * These are ONLY sent by chan_iax2 and I'm not convinced that + * they are useful. I haven't deleted them entirely because I + * just am not sure of the ramifications of removing them. */ if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) { - ast_channel_setoption(other, ntohs(aoh->option), aoh->data, - f->datalen - sizeof(struct ast_option_header), 0); + switch (ntohs(aoh->option)) { + case AST_OPTION_TONE_VERIFY: + case AST_OPTION_TDD: + case AST_OPTION_RELAXDTMF: + case AST_OPTION_AUDIO_MODE: + ast_channel_setoption(other, ntohs(aoh->option), aoh->data, + f->datalen - sizeof(struct ast_option_header), 0); + } } break; }