]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_diversion: Fix adding more than one histinfo to Supported
authorIvan Poddubnyi <ivan.poddubny@gmail.com>
Mon, 28 Dec 2020 12:43:23 +0000 (13:43 +0100)
committerGeorge Joseph <gjoseph@digium.com>
Thu, 18 Feb 2021 16:35:07 +0000 (10:35 -0600)
New responses sent within a PJSIP sessions are based on those that were
sent before. Therefore, adding/modifying a header once causes it to be
sent on all responses that follow.

Sending 181 Call Is Being Forwarded many times first adds "histinfo"
duplicated more and more, and eventually overflows past the array
boundary.

This commit adds a check preventing adding "histinfo" more than once,
and skipping it if there is no more space in the header.

Similar overflow situations can also occur in res_pjsip_path and
res_pjsip_outbound_registration so those were also modified to
check the bounds and suppress duplicate Supported values.

ASTERISK-29227
Reported by: Ivan Poddubny

Change-Id: Id43704a1f1a0293e35cc7f844026f0b04f2ac322

res/res_pjsip_diversion.c
res/res_pjsip_outbound_registration.c
res/res_pjsip_path.c

index 24d178199e67b4841b19ab5cba1fc6ae291ff6f5..1cc6e0827f1331519d3e48dccbcca7fdf213260d 100644 (file)
@@ -120,6 +120,7 @@ static enum AST_REDIRECTING_REASON cause_to_reason(const unsigned long cause) {
 static int add_supported(pjsip_tx_data *tdata)
 {
        pjsip_supported_hdr *hdr;
+       unsigned int i;
 
        hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
        if (!hdr) {
@@ -132,6 +133,19 @@ static int add_supported(pjsip_tx_data *tdata)
                pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
        }
 
+       /* Asterisk can send multiple "181 Call forwarded" in a single session,
+        * we might have already modified Supported before
+        */
+       for (i = 0; i < hdr->count; ++i) {
+               if (pj_stricmp(&hdr->values[i], &HISTINFO_SUPPORTED_NAME) == 0) {
+                       return 0;
+               }
+       }
+
+       if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
+               return -1;
+       }
+
        /* add on to the existing Supported header */
        pj_strassign(&hdr->values[hdr->count++], &HISTINFO_SUPPORTED_NAME);
 
index 2c5898620a957c7e1d64700bd4ccab2c9662e4de..99da044529d9cc19a6bf8a627c2c7f39dd412d57 100644 (file)
@@ -615,6 +615,7 @@ static pj_status_t registration_client_send(struct sip_outbound_registration_cli
 static int add_to_supported_header(pjsip_tx_data *tdata, pj_str_t *name)
 {
        pjsip_supported_hdr *hdr;
+       int i;
 
        hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
        if (!hdr) {
@@ -628,6 +629,17 @@ static int add_to_supported_header(pjsip_tx_data *tdata, pj_str_t *name)
                pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
        }
 
+       /* Don't add the value if it's already there */
+       for (i = 0; i < hdr->count; ++i) {
+               if (pj_stricmp(&hdr->values[i], name) == 0) {
+                       return 1;
+               }
+       }
+
+       if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
+               return 0;
+       }
+
        /* add on to the existing Supported header */
        pj_strassign(&hdr->values[hdr->count++], name);
 
index adc5a8cf36b3c3031e4a3cb270a221fe18b13255..9f48009e54be68c4983d2fa6747da96ed4d428e2 100644 (file)
@@ -123,6 +123,7 @@ static int path_get_string(pj_pool_t *pool, struct ast_sip_contact *contact, pj_
 static int add_supported(pjsip_tx_data *tdata)
 {
        pjsip_supported_hdr *hdr;
+       int i;
 
        hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
        if (!hdr) {
@@ -135,6 +136,17 @@ static int add_supported(pjsip_tx_data *tdata)
                pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
        }
 
+       /* Don't add the value if it's already there */
+       for (i = 0; i < hdr->count; ++i) {
+               if (pj_stricmp(&hdr->values[i], &PATH_SUPPORTED_NAME) == 0) {
+                       return 0;
+               }
+       }
+
+       if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
+               return -1;
+       }
+
        /* add on to the existing Supported header */
        pj_strassign(&hdr->values[hdr->count++], &PATH_SUPPORTED_NAME);