From dba13a43b10e62490f835fb92c60f35be2fdedaf Mon Sep 17 00:00:00 2001 From: Bogdan-Andrei Iancu Date: Thu, 23 Jan 2025 13:10:33 +0200 Subject: [PATCH] Fix dangling parsed_uri structure in to_body Whenever the SIP URI parsing fails, be sure you reset to_body->parsed_uri, as other functions may later try to use it and we want to have it in a consistent format. The issue was reported by @vladpaiu Closes #3557 (cherry picked from commit 021172b5ea1db1f80489280c4f4913b4beb14cbd) --- modules/b2b_logic/logic.c | 4 +--- modules/sip_i/sip_i.c | 2 +- modules/sipmsgops/sipmsgops.c | 32 +++++++------------------------- parser/parse_to.c | 17 +++++++++++++++++ parser/parse_to.h | 6 +++++- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/modules/b2b_logic/logic.c b/modules/b2b_logic/logic.c index 8f02dd99cff..bd53f7d4af9 100644 --- a/modules/b2b_logic/logic.c +++ b/modules/b2b_logic/logic.c @@ -2238,9 +2238,7 @@ int b2b_logic_notify(int src, struct sip_msg* msg, str* key, int type, str* b2bl { if(msg->first_line.u.request.method_value==METHOD_REFER && parse_refer_to_header(msg)==0 && msg->refer_to!=NULL && - get_refer_to(msg)!=NULL && parse_uri(get_refer_to(msg)->uri.s, - get_refer_to(msg)->uri.len, - &(get_refer_to(msg)->parsed_uri))==0) + parse_to_body_uri( get_refer_to(msg) )==0 ) { /* We have a Refer-To header */ if(get_refer_to(msg)->parsed_uri.headers.s && diff --git a/modules/sip_i/sip_i.c b/modules/sip_i/sip_i.c index 53336beb0c5..481a383df43 100644 --- a/modules/sip_i/sip_i.c +++ b/modules/sip_i/sip_i.c @@ -1320,7 +1320,7 @@ static int init_iam_default(struct sip_msg *sip_msg, struct isup_parsed_struct * goto cgpn_err; } pai = get_pai(sip_msg); - if (parse_uri(pai->uri.s, pai->uri.len, &pai->parsed_uri) < 0) { + if (parse_to_body_uri(pai) < 0) { LM_ERR("Unable to parse P-Asserted-Identity URI\n"); goto cgpn_err; } diff --git a/modules/sipmsgops/sipmsgops.c b/modules/sipmsgops/sipmsgops.c index 68d40c9f14b..9b778abd0fe 100644 --- a/modules/sipmsgops/sipmsgops.c +++ b/modules/sipmsgops/sipmsgops.c @@ -1619,8 +1619,8 @@ static int w_sip_validate(struct sip_msg *msg, void *_flags, pv_spec_t* err_txt) struct hdr_field * ptr; contact_t * contacts; struct sip_uri test_contacts; + struct sip_uri *p_uri; struct cseq_body * cbody; - struct to_body *from, *to; pv_value_t pv_val; char reason[MAX_REASON]; int ret = -SV_GENERIC_FAILURE; @@ -1707,30 +1707,21 @@ static int w_sip_validate(struct sip_msg *msg, void *_flags, pv_spec_t* err_txt) /* test to header uri */ if(flags & SIP_PARSE_TO) { - if(!msg->to->parsed) { - if(parse_to_header(msg) < 0) { - strcpy(reason, "failed to parse 'To' header"); - ret = SV_TO_PARSE_ERROR; - goto failed; - } - } - - to = (struct to_body*)msg->to->parsed; - if(parse_uri(to->uri.s, to->uri.len, &to->parsed_uri) < 0) { + if ( (p_uri=parse_to_uri(msg))==NULL ) { strcpy(reason, "failed to parse 'To' header"); ret = SV_TO_PARSE_ERROR; goto failed; } /* check for valid domain format */ - if(check_hostname(&to->parsed_uri.host) < 0) { + if(check_hostname(&p_uri->host) < 0) { strcpy(reason, "invalid domain for 'To' header"); ret = SV_TO_DOMAIN_ERROR; goto failed; } - if(!is_username_str(&to->parsed_uri.user)) { + if(!is_username_str(&p_uri->user)) { strcpy(reason, "invalid username for 'To' header"); ret = SV_TO_USERNAME_ERROR; goto failed; @@ -1739,30 +1730,21 @@ static int w_sip_validate(struct sip_msg *msg, void *_flags, pv_spec_t* err_txt) /* test from header uri */ if(flags & SIP_PARSE_FROM) { - if(!msg->from->parsed) { - if(parse_from_header(msg) < 0) { - strcpy(reason, "failed to parse 'From' header"); - ret = SV_FROM_PARSE_ERROR; - goto failed; - } - } - - from = (struct to_body*)msg->from->parsed; - if(parse_uri(from->uri.s, from->uri.len, &from->parsed_uri) < 0) { + if ( (p_uri=parse_from_uri(msg))==NULL ) { strcpy(reason, "failed to parse 'From' header"); ret = SV_FROM_PARSE_ERROR; goto failed; } /* check for valid domain format */ - if(check_hostname(&from->parsed_uri.host) < 0) { + if(check_hostname(&p_uri->host) < 0) { strcpy(reason, "invalid domain for 'From' header"); ret = SV_FROM_DOMAIN_ERROR; goto failed; } - if (!is_username_str(&from->parsed_uri.user)) { + if (!is_username_str(&p_uri->user)) { strcpy(reason, "invalid username for 'From' header"); ret = SV_FROM_USERNAME_ERROR; goto failed; diff --git a/parser/parse_to.c b/parser/parse_to.c index 498705d93b1..a38c133c061 100644 --- a/parser/parse_to.c +++ b/parser/parse_to.c @@ -903,3 +903,20 @@ int parse_to_header( struct sip_msg *msg) error: return -1; } + + +/* + * Parses the URI from a generic to_body structure + * Helper function (not specific to TO hdr) + */ +int parse_to_body_uri(struct to_body *to_b) +{ + if (to_b==NULL) + return -1; + + if (parse_uri(to_b->uri.s, to_b->uri.len, &to_b->parsed_uri) < 0) { + memset( &to_b->parsed_uri, 0, sizeof(struct sip_uri)); + return -1; + } + return 0; +} diff --git a/parser/parse_to.h b/parser/parse_to.h index 180d0976e25..db739fe24ea 100644 --- a/parser/parse_to.h +++ b/parser/parse_to.h @@ -43,7 +43,9 @@ struct to_body{ str uri; /* URI */ str display; /* Display Name */ str tag_value; /* Value of tag */ - struct sip_uri parsed_uri; /* Parsed URI */ + struct sip_uri parsed_uri; /* Parsed URI + * IMPORTANT - be sure you set it to 0 + * upon parse URI failure !!!!!! */ struct to_param *param_lst; /* Linked list of parameters */ struct to_param *last_param; /* Last parameter in the list */ struct to_body *next; /* Next body if multi-instance header */ @@ -69,4 +71,6 @@ void free_to_params(struct to_body *tb); char* parse_multi_to(char* buffer, char *end, struct to_body *to_b); +int parse_to_body_uri(struct to_body *to_b); + #endif