summaryrefslogtreecommitdiff
path: root/channels/chan_skinny.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2012-05-29 18:40:26 +0000
committerMatthew Jordan <mjordan@digium.com>2012-05-29 18:40:26 +0000
commit94187aafc0953c19e738c6f08b0c6c77ee63170c (patch)
tree7fc401e75b15e88a32add8642bcb42e8ef6f8866 /channels/chan_skinny.c
parent2d418b596cee6c1632e8a0f3e07a2e345dc3c98d (diff)
AST-2012-008: Fix remote crash vulnerability in chan_skinny
When a skinny session is unregistered, the corresponding device pointer is set to NULL in the channel private data. If the client was not in the on-hook state at the time the connection was closed, the device pointer can later be dereferened if a message or channel event attempts to use a line's pointer to said device. The patches prevent this from occurring by checking the line's pointer in message handlers and channel callbacks that can fire after an unregistration attempt. (closes issue ASTERISK-19905) Reported by: Christoph Hebeisen Tested by: mjordan, Damien Wedhorn Patches: AST-2012-008-1.8.diff uploaded by mjordan (license 6283) AST-2012-008-10.diff uploaded by mjordan (licesen 6283) ........ Merged revisions 367844 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@367845 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_skinny.c')
-rw-r--r--channels/chan_skinny.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index cace12ee9..753d7aeba 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -3143,6 +3143,10 @@ static void update_connectedline(struct skinny_subchannel *sub, const void *data
struct skinny_line *l = sub->line;
struct skinny_device *d = l->device;
+ if (!d) {
+ return;
+ }
+
if (!ast_channel_caller(c)->id.number.valid
|| ast_strlen_zero(ast_channel_caller(c)->id.number.str)
|| !ast_channel_connected(c)->id.number.valid
@@ -4263,6 +4267,11 @@ static void *skinny_ss(void *data)
int res = 0;
int loop_pause = 100;
+ if (!d) {
+ ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
+ return NULL;
+ }
+
ast_verb(3, "Starting simple switch on '%s@%s'\n", l->name, d->name);
len = strlen(sub->exten);
@@ -4373,7 +4382,7 @@ static int skinny_call(struct ast_channel *ast, const char *dest, int timeout)
struct ast_var_t *current;
int doautoanswer = 0;
- if (!d->registered) {
+ if (!d || !d->registered) {
ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
return -1;
}
@@ -4772,7 +4781,13 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
struct skinny_subchannel *sub = ast_channel_tech_pvt(ast);
struct skinny_line *l = sub->line;
struct skinny_device *d = l->device;
- struct skinnysession *s = d->session;
+ struct skinnysession *s;
+
+ if (!d) {
+ ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
+ return -1;
+ }
+ s = d->session;
if (!s) {
ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast_channel_name(ast));
@@ -5512,6 +5527,11 @@ static int handle_transfer_button(struct skinny_subchannel *sub)
l = sub->line;
d = l->device;
+ if (!d) {
+ ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
+ return -1;
+ }
+
if (!sub->related) {
/* Another sub has not been created so this must be first XFER press */
if (!(sub->substate == SUBSTATE_HOLD)) {
@@ -5556,6 +5576,11 @@ static int handle_callforward_button(struct skinny_subchannel *sub, int cfwdtype
struct skinny_device *d = l->device;
struct ast_channel *c = sub->owner;
+ if (!d) {
+ ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
+ return 0;
+ }
+
if (d->hookstate == SKINNY_ONHOOK) {
d->hookstate = SKINNY_OFFHOOK;
transmit_speaker_mode(d, SKINNY_SPEAKERON);