diff options
author | Kinsey Moore <kmoore@digium.com> | 2012-05-04 22:17:38 +0000 |
---|---|---|
committer | Kinsey Moore <kmoore@digium.com> | 2012-05-04 22:17:38 +0000 |
commit | 781f4657b91d6c8fa3dcf3bc9f0daaad5155506e (patch) | |
tree | 02eb58c52c581367e9fb47d8de1c633b2b094030 /channels | |
parent | 8842f76a7f486cd3d223a2c28ace91fcab5e8a12 (diff) |
Fix many issues from the NULL_RETURNS Coverity report
Most of the changes here are trivial NULL checks. There are a couple
optimizations to remove the need to check for NULL and outboundproxy parsing
in chan_sip.c was rewritten to avoid use of strtok. Additionally, a bug was
found and fixed with the parsing of outboundproxy when "outboundproxy=," was
set.
(Closes issue ASTERISK-19654)
........
Merged revisions 365398 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 365399 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@365400 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_iax2.c | 9 | ||||
-rw-r--r-- | channels/chan_sip.c | 99 | ||||
-rw-r--r-- | channels/sip/config_parser.c | 1 |
3 files changed, 70 insertions, 39 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index acc585372..baee946f2 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -13060,6 +13060,11 @@ static int set_config(const char *config_file, int reload) ast_config_destroy(ucfg); return 0; } + if (!cfg) { + /* should have been able to load the config here */ + ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file); + return -1; + } } else if (cfg == CONFIG_STATUS_FILEINVALID) { ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); return 0; @@ -13937,7 +13942,9 @@ static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *dat } else if (!strncasecmp(colname, "codec[", 6)) { char *codecnum, *ptr; struct ast_format tmpfmt; - codecnum = strchr(colname, '['); + + /* skip over "codec" to the '[' */ + codecnum = colname + 5; *codecnum = '\0'; codecnum++; if ((ptr = strchr(codecnum, ']'))) { diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 8579a9638..71ca637fc 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -15775,7 +15775,9 @@ static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, c char *end_quote; rname = tmp + 1; end_quote = strchr(rname, '\"'); - *end_quote = '\0'; + if (end_quote) { + *end_quote = '\0'; + } } if (number) { @@ -25219,6 +25221,7 @@ static int cc_esc_publish_handler(struct sip_pvt *pvt, struct sip_request *req, * document earlier. So there's no need to enclose this operation in an if statement. */ tuple_children = ast_xml_node_get_children(tuple_node); + /* coverity[null_returns: FALSE] */ status_node = ast_xml_find_element(tuple_children, "status", NULL, NULL); if (!(status_children = ast_xml_node_get_children(status_node))) { @@ -25550,7 +25553,8 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sip_peer *authpeer = NULL; const char *eventheader = sip_get_header(req, "Event"); /* Get Event package name */ int resubscribe = (p->subscribed != NONE) && !req->ignore; - char *temp, *event; + char *event_end; + ptrdiff_t event_len = 0; if (p->initreq.headers) { /* We already have a dialog */ @@ -25612,13 +25616,10 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, return 0; } - if ( (strchr(eventheader, ';'))) { - event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ - temp = strchr(event, ';'); - *temp = '\0'; /* Remove any options for now */ - /* We might need to use them later :-) */ - } else - event = (char *) eventheader; /* XXX is this legal ? */ + event_end = strchr(eventheader, ';'); + if (event_end) { + event_len = event_end - eventheader; + } /* Handle authentication if we're new and not a retransmission. We can't just * use if !req->ignore, because then we'll end up sending @@ -25657,7 +25658,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, return 0; } - if (strcmp(event, "message-summary") && strcmp(event, "call-completion")) { + if (strncmp(eventheader, "message-summary", MAX(event_len, 15)) && strncmp(eventheader, "call-completion", MAX(event_len, 15))) { /* Get destination right away */ gotdest = get_destination(p, NULL, NULL); } @@ -25683,7 +25684,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, if (ast_strlen_zero(p->tag)) make_our_tag(p->tag, sizeof(p->tag)); - if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ + if (!strncmp(eventheader, "presence", MAX(event_len, 8)) || !strncmp(eventheader, "dialog", MAX(event_len, 6))) { /* Presence, RFC 3842 */ unsigned int pidf_xml; const char *accept; int start = 0; @@ -25761,7 +25762,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, } else { p->subscribed = subscribed; } - } else if (!strcmp(event, "message-summary")) { + } else if (!strncmp(eventheader, "message-summary", MAX(event_len, 15))) { int start = 0; int found_supported = 0; const char *acceptheader; @@ -25826,11 +25827,11 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, p->relatedpeer = sip_ref_peer(authpeer, "setting dialog's relatedpeer pointer"); } /* Do not release authpeer here */ - } else if (!strcmp(event, "call-completion")) { + } else if (!strncmp(eventheader, "call-completion", MAX(event_len, 15))) { handle_cc_subscribe(p, req); } else { /* At this point, Asterisk does not understand the specified event */ transmit_response(p, "489 Bad Event", req); - ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event); + ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", eventheader); pvt_set_needdestroy(p, "unknown event package"); if (authpeer) { sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 5)"); @@ -28525,32 +28526,42 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str } else if (!strcasecmp(v->name, "fromuser")) { ast_string_field_set(peer, fromuser, v->value); } else if (!strcasecmp(v->name, "outboundproxy")) { - char *tok, *proxyname; + char *host, *proxyname, *sep; if (ast_strlen_zero(v->value)) { - ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno); + ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); continue; } - peer->outboundproxy = - ao2_alloc(sizeof(*peer->outboundproxy), NULL); - - tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); - - sip_parse_host(tok, v->lineno, &proxyname, - &peer->outboundproxy->port, - &peer->outboundproxy->transport); + if (!peer->outboundproxy) { + peer->outboundproxy = ao2_alloc(sizeof(*peer->outboundproxy), NULL); + if (!peer->outboundproxy) { + ast_log(LOG_WARNING, "Unable to allocate config storage for outboundproxy\n"); + continue; + } + } - tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); + host = ast_strdupa(v->value); + if (!host) { + ast_log(LOG_WARNING, "Unable to allocate stack space for parsing outboundproxy\n"); + continue; + } - if ((tok = strtok(NULL, ","))) { - peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(tok), "force", 5); + host = ast_skip_blanks(host); + sep = strchr(host, ','); + if (sep) { + *sep++ = '\0'; + peer->outboundproxy->force = !strncasecmp(ast_skip_blanks(sep), "force", 5); } else { peer->outboundproxy->force = FALSE; } + sip_parse_host(host, v->lineno, &proxyname, + &peer->outboundproxy->port, + &peer->outboundproxy->transport); + if (ast_strlen_zero(proxyname)) { - ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno); + ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf\n", v->lineno); sip_cfg.outboundproxy.name[0] = '\0'; continue; } @@ -29141,6 +29152,11 @@ static int reload_config(enum channelreloadreason reason) ast_config_destroy(ucfg); return 1; } + if (!cfg) { + /* should have been able to reload here */ + ast_log(LOG_NOTICE, "Unable to load config %s\n", config); + return -1; + } } else if (cfg == CONFIG_STATUS_FILEINVALID) { ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", config); return 1; @@ -29557,27 +29573,34 @@ static int reload_config(enum channelreloadreason reason) default_fromdomainport = STANDARD_SIP_PORT; } } else if (!strcasecmp(v->name, "outboundproxy")) { - char *tok, *proxyname; + char *host, *proxyname, *sep; if (ast_strlen_zero(v->value)) { - ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno); + ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf\n", v->lineno); continue; } - tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ",")); - - sip_parse_host(tok, v->lineno, &proxyname, - &sip_cfg.outboundproxy.port, - &sip_cfg.outboundproxy.transport); + host = ast_strdupa(v->value); + if (!host) { + ast_log(LOG_WARNING, "Unable to allocate stack space for parsing outboundproxy\n"); + continue; + } - if ((tok = strtok(NULL, ","))) { - sip_cfg.outboundproxy.force = !strncasecmp(ast_skip_blanks(tok), "force", 5); + host = ast_skip_blanks(host); + sep = strchr(host, ','); + if (sep) { + *sep++ = '\0'; + sip_cfg.outboundproxy.force = !strncasecmp(ast_skip_blanks(sep), "force", 5); } else { sip_cfg.outboundproxy.force = FALSE; } + sip_parse_host(host, v->lineno, &proxyname, + &sip_cfg.outboundproxy.port, + &sip_cfg.outboundproxy.transport); + if (ast_strlen_zero(proxyname)) { - ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno); + ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf\n", v->lineno); sip_cfg.outboundproxy.name[0] = '\0'; continue; } diff --git a/channels/sip/config_parser.c b/channels/sip/config_parser.c index 55695e545..4a03189f6 100644 --- a/channels/sip/config_parser.c +++ b/channels/sip/config_parser.c @@ -638,6 +638,7 @@ int sip_parse_host(char *line, int lineno, char **hostname, int *portnum, enum s char *port; if (ast_strlen_zero(line)) { + *hostname = NULL; return -1; } if ((*hostname = strstr(line, "://"))) { |