Merged revisions 308903 via svnmerge from
authorRichard Mudgett <rmudgett@digium.com>
Thu, 24 Feb 2011 21:43:32 +0000 (21:43 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 24 Feb 2011 21:43:32 +0000 (21:43 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r308903 | rmudgett | 2011-02-24 15:38:41 -0600 (Thu, 24 Feb 2011) | 9 lines

  Invalid read in ast_channel_set_caller_event().

  Valgrind reported that ast_channel_set_caller_event() was reading data
  from a freed buffer when using the pre_set structure.

  Rearange things to pre-calculate the name and number pointer before
  updating the caller party structure to see if the name or number was
  changed.
........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@308904 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/channel.c

index 4047328..cba634b 100644 (file)
@@ -6799,7 +6799,8 @@ void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_cal
 
 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
 {
-       struct ast_party_caller pre_set;
+       const char *pre_set_number;
+       const char *pre_set_name;
 
        if (&chan->caller == caller) {
                /* Don't set to self */
@@ -6807,12 +6808,14 @@ void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_par
        }
 
        ast_channel_lock(chan);
-       pre_set = chan->caller;
+       pre_set_number =
+               S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL);
+       pre_set_name = S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL);
        ast_party_caller_set(&chan->caller, caller, update);
-       if (S_COR(pre_set.id.number.valid, pre_set.id.number.str, NULL)
-                       != S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
-               || S_COR(pre_set.id.name.valid, pre_set.id.name.str, NULL)
-                       != S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)) {
+       if (S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
+                       != pre_set_number
+               || S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)
+                       != pre_set_name) {
                /* The caller id name or number changed. */
                report_new_callerid(chan);
        }