From c7d7efd2302b561e0d321c7e9c426396174bf6cc Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Sun, 8 Feb 2015 10:23:22 +0100 Subject: [PATCH] fix realloc failure issues detected thanks to cppcheck --- minissdpd/listifaces.c | 17 ++++- minissdpd/minissdpd.c | 16 ++-- miniupnpc/testigddescparse.c | 10 ++- miniupnpc/wingenminiupnpcstrings.c | 5 +- miniupnpd/natpmp.c | 4 +- miniupnpd/netfilter/iptcrdr.c | 115 +++++++++++++++++++++-------- miniupnpd/netfilter/iptpinhole.c | 20 ++++- miniupnpd/pf/obsdrdr.c | 11 ++- 8 files changed, 143 insertions(+), 55 deletions(-) diff --git a/minissdpd/listifaces.c b/minissdpd/listifaces.c index f893d6e..190ee21 100644 --- a/minissdpd/listifaces.c +++ b/minissdpd/listifaces.c @@ -1,5 +1,5 @@ -/* $Id: listifaces.c,v 1.6 2014/02/03 14:32:14 nanard Exp $ */ -/* (c) 2006-2014 Thomas BERNARD +/* $Id: listifaces.c,v 1.7 2015/02/08 08:51:54 nanard Exp $ */ +/* (c) 2006-2015 Thomas BERNARD * http://miniupnp.free.fr/ http://miniupnp.tuxfamily.org/ */ #include @@ -49,11 +49,20 @@ void listifaces(void) /*s = socket(PF_INET, SOCK_DGRAM, 0);*/ s = socket(AF_INET, SOCK_DGRAM, 0); do { + char * tmp; #ifdef __linux__ buflen += buflen; #endif - if(buflen > 0) - buf = realloc(buf, buflen); + if(buflen > 0) { + tmp = realloc(buf, buflen); + if(!tmp) { + fprintf(stderr, "error allocating %d bytes.\n", buflen); + close(f); + free(buf); + return; + } + buf = tmp; + } ifc.ifc_len = buflen; ifc.ifc_buf = (caddr_t)buf; if(ioctl(s, SIOCGIFCONF, &ifc) < 0) diff --git a/minissdpd/minissdpd.c b/minissdpd/minissdpd.c index 359c2eb..adaa72e 100644 --- a/minissdpd/minissdpd.c +++ b/minissdpd/minissdpd.c @@ -1,6 +1,6 @@ -/* $Id: minissdpd.c,v 1.44 2014/12/05 17:31:46 nanard Exp $ */ +/* $Id: minissdpd.c,v 1.45 2015/02/08 08:51:54 nanard Exp $ */ /* MiniUPnP project - * (c) 2007-2014 Thomas Bernard + * (c) 2007-2015 Thomas Bernard * website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -196,7 +196,8 @@ add_to_buffer(struct reqelem * req, const unsigned char * data, int len) } tmp = realloc(req->output_buffer, req->output_buffer_len + len); if(tmp == NULL) { - syslog(LOG_ERR, "%s: failed to allocate %d bytes", __func__, req->output_buffer_len + len); + syslog(LOG_ERR, "%s: failed to allocate %d bytes", + __func__, req->output_buffer_len + len); return -1; } req->output_buffer = tmp; @@ -269,13 +270,16 @@ updateDevice(const struct header * headers, time_t t) /* update Location ! */ if(headers[HEADER_LOCATION].l > p->headers[HEADER_LOCATION].l) { - p = realloc(p, sizeof(struct device) - + headers[0].l+headers[1].l+headers[2].l ); - if(!p) /* allocation error */ + struct device * tmp; + tmp = realloc(p, sizeof(struct device) + + headers[0].l+headers[1].l+headers[2].l); + if(!tmp) /* allocation error */ { syslog(LOG_ERR, "updateDevice() : memory allocation error"); + free(p); return 0; } + p = tmp; *pp = p; } memcpy(p->data + p->headers[0].l + p->headers[1].l, diff --git a/miniupnpc/testigddescparse.c b/miniupnpc/testigddescparse.c index fced102..c70ec6a 100644 --- a/miniupnpc/testigddescparse.c +++ b/miniupnpc/testigddescparse.c @@ -1,8 +1,8 @@ -/* $Id: testigddescparse.c,v 1.7 2014/11/17 19:28:20 nanard Exp $ */ +/* $Id: testigddescparse.c,v 1.8 2015/02/08 08:46:06 nanard Exp $ */ /* Project : miniupnp * http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2008-2014 Thomas Bernard + * Copyright (c) 2008-2015 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ @@ -155,6 +155,11 @@ int main(int argc, char * * argv) len = ftell(f); fseek(f, 0, SEEK_SET); buffer = malloc(len); + if(!buffer) { + fprintf(stderr, "Memory allocation error.\n"); + fclose(f); + return 1; + } fread(buffer, 1, len, f); fclose(f); f = NULL; @@ -162,6 +167,7 @@ int main(int argc, char * * argv) f = fopen(argv[2], "r"); if(!f) { fprintf(stderr, "Cannot open %s for reading.\n", argv[2]); + free(buffer); return 1; } } diff --git a/miniupnpc/wingenminiupnpcstrings.c b/miniupnpc/wingenminiupnpcstrings.c index fd9ee06..50df06a 100644 --- a/miniupnpc/wingenminiupnpcstrings.c +++ b/miniupnpc/wingenminiupnpcstrings.c @@ -1,8 +1,8 @@ -/* $Id: wingenminiupnpcstrings.c,v 1.2 2011/01/11 15:31:13 nanard Exp $ */ +/* $Id: wingenminiupnpcstrings.c,v 1.4 2015/02/08 08:46:06 nanard Exp $ */ /* Project: miniupnp * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * Author: Thomas Bernard - * Copyright (c) 2005-2009 Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENSE file provided within this distribution */ #include @@ -59,6 +59,7 @@ int main(int argc, char * * argv) { fout = fopen(argv[2], "w"); if(!fout) { fprintf(stderr, "Cannot open %s for writing.\n", argv[2]); + fclose(fin); return 1; } n = 0; diff --git a/miniupnpd/natpmp.c b/miniupnpd/natpmp.c index 0ae0954..455748e 100644 --- a/miniupnpd/natpmp.c +++ b/miniupnpd/natpmp.c @@ -1,6 +1,6 @@ -/* $Id: natpmp.c,v 1.47 2014/05/19 12:51:52 nanard Exp $ */ +/* $Id: natpmp.c,v 1.51 2015/02/08 09:18:15 nanard Exp $ */ /* MiniUPnP project - * (c) 2007-2014 Thomas Bernard + * (c) 2007-2015 Thomas Bernard * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ diff --git a/miniupnpd/netfilter/iptcrdr.c b/miniupnpd/netfilter/iptcrdr.c index e5951e8..99678e7 100644 --- a/miniupnpd/netfilter/iptcrdr.c +++ b/miniupnpd/netfilter/iptcrdr.c @@ -1,7 +1,7 @@ -/* $Id: iptcrdr.c,v 1.50 2012/10/03 14:49:08 nanard Exp $ */ +/* $Id: iptcrdr.c,v 1.53 2015/02/08 09:10:00 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2011 Thomas Bernard + * (c) 2006-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ #include @@ -1083,25 +1083,37 @@ addnatrule(int proto, unsigned short eport, { int r = 0; struct ipt_entry * e; + struct ipt_entry * tmp; struct ipt_entry_match *match = NULL; struct ipt_entry_target *target = NULL; e = calloc(1, sizeof(struct ipt_entry)); - e->ip.proto = proto; - if(proto == IPPROTO_TCP) - { - match = get_tcp_match(eport, 0); + if(!e) { + syslog(LOG_ERR, "%s: calloc(%d) error", "addnatrule", + (int)sizeof(struct ipt_entry)); + return -1; } - else - { + e->ip.proto = proto; + if(proto == IPPROTO_TCP) { + match = get_tcp_match(eport, 0); + } else { match = get_udp_match(eport, 0); } e->nfcache = NFC_IP_DST_PT; target = get_dnat_target(iaddr, iport); e->nfcache |= NFC_UNKNOWN; - e = realloc(e, sizeof(struct ipt_entry) + tmp = realloc(e, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size); + if(!tmp) { + syslog(LOG_ERR, "%s: realloc(%d) error", "addnatrule", + (int)(sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size)); + free(e); + free(match); + free(target); + return -1; + } + e = tmp; memcpy(e->elems, match, match->u.match_size); memcpy(e->elems + match->u.match_size, target, target->u.target_size); e->target_offset = sizeof(struct ipt_entry) @@ -1110,8 +1122,7 @@ addnatrule(int proto, unsigned short eport, + match->u.match_size + target->u.target_size; /* remote host */ - if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*"))) - { + if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*"))) { e->ip.src.s_addr = inet_addr(rhost); e->ip.smsk.s_addr = INADDR_NONE; } @@ -1134,26 +1145,38 @@ addpeernatrule(int proto, { int r = 0; struct ipt_entry * e; + struct ipt_entry * tmp; struct ipt_entry_match *match = NULL; struct ipt_entry_target *target = NULL; e = calloc(1, sizeof(struct ipt_entry)); + if(!e) { + syslog(LOG_ERR, "%s: calloc(%d) error", "addpeernatrule", + (int)sizeof(struct ipt_entry)); + return -1; + } e->ip.proto = proto; /* TODO: Fill port matches and SNAT */ - if(proto == IPPROTO_TCP) - { + if(proto == IPPROTO_TCP) { match = get_tcp_match(rport, iport); - } - else - { + } else { match = get_udp_match(rport, iport); } e->nfcache = NFC_IP_DST_PT | NFC_IP_SRC_PT; target = get_snat_target(eaddr, eport); e->nfcache |= NFC_UNKNOWN; - e = realloc(e, sizeof(struct ipt_entry) + tmp = realloc(e, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size); + if(!tmp) { + syslog(LOG_ERR, "%s: realloc(%d) error", "addpeernatrule", + (int)(sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size)); + free(e); + free(match); + free(target); + return -1; + } + e = tmp; memcpy(e->elems, match, match->u.match_size); memcpy(e->elems + match->u.match_size, target, target->u.target_size); e->target_offset = sizeof(struct ipt_entry) @@ -1192,26 +1215,38 @@ addpeerdscprule(int proto, unsigned char dscp, { int r = 0; struct ipt_entry * e; + struct ipt_entry * tmp; struct ipt_entry_match *match = NULL; struct ipt_entry_target *target = NULL; e = calloc(1, sizeof(struct ipt_entry)); + if(!e) { + syslog(LOG_ERR, "%s: calloc(%d) error", "addpeerdscprule", + (int)sizeof(struct ipt_entry)); + return -1; + } e->ip.proto = proto; /* TODO: Fill port matches and SNAT */ - if(proto == IPPROTO_TCP) - { + if(proto == IPPROTO_TCP) { match = get_tcp_match(rport, iport); - } - else - { + } else { match = get_udp_match(rport, iport); } e->nfcache = NFC_IP_DST_PT | NFC_IP_SRC_PT; target = get_dscp_target(dscp); e->nfcache |= NFC_UNKNOWN; - e = realloc(e, sizeof(struct ipt_entry) + tmp = realloc(e, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size); + if(!tmp) { + syslog(LOG_ERR, "%s: realloc(%d) error", "addpeerdscprule", + (int)(sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size)); + free(e); + free(match); + free(target); + return -1; + } + e = tmp; memcpy(e->elems, match, match->u.match_size); memcpy(e->elems + match->u.match_size, target, target->u.target_size); e->target_offset = sizeof(struct ipt_entry) @@ -1264,17 +1299,20 @@ add_filter_rule(int proto, const char * rhost, { int r = 0; struct ipt_entry * e; + struct ipt_entry * tmp; struct ipt_entry_match *match = NULL; struct ipt_entry_target *target = NULL; e = calloc(1, sizeof(struct ipt_entry)); - e->ip.proto = proto; - if(proto == IPPROTO_TCP) - { - match = get_tcp_match(iport,0); + if(!e) { + syslog(LOG_ERR, "%s: calloc(%d) error", "add_filter_rule", + (int)sizeof(struct ipt_entry)); + return -1; } - else - { + e->ip.proto = proto; + if(proto == IPPROTO_TCP) { + match = get_tcp_match(iport,0); + } else { match = get_udp_match(iport,0); } e->nfcache = NFC_IP_DST_PT; @@ -1282,9 +1320,18 @@ add_filter_rule(int proto, const char * rhost, e->ip.dmsk.s_addr = INADDR_NONE; target = get_accept_target(); e->nfcache |= NFC_UNKNOWN; - e = realloc(e, sizeof(struct ipt_entry) + tmp = realloc(e, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size); + if(!tmp) { + syslog(LOG_ERR, "%s: realloc(%d) error", "add_filter_rule", + (int)(sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size)); + free(e); + free(match); + free(target); + return -1; + } + e = tmp; memcpy(e->elems, match, match->u.match_size); memcpy(e->elems + match->u.match_size, target, target->u.target_size); e->target_offset = sizeof(struct ipt_entry) @@ -1374,15 +1421,19 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport, { if(*number >= capacity) { + unsigned short * tmp; /* need to increase the capacity of the array */ - array = realloc(array, sizeof(unsigned short)*capacity); - if(!array) + tmp = realloc(array, sizeof(unsigned short)*capacity); + if(!tmp) { syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%u) error", (unsigned)sizeof(unsigned short)*capacity); *number = 0; + free(array); + array = NULL; break; } + array = tmp; array[*number] = eport; (*number)++; } diff --git a/miniupnpd/netfilter/iptpinhole.c b/miniupnpd/netfilter/iptpinhole.c index 5cb0e0e..286868a 100644 --- a/miniupnpd/netfilter/iptpinhole.c +++ b/miniupnpd/netfilter/iptpinhole.c @@ -1,7 +1,7 @@ -/* $Id: iptpinhole.c,v 1.8 2012/09/18 08:29:17 nanard Exp $ */ +/* $Id: iptpinhole.c,v 1.12 2015/02/08 09:16:50 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2012 Thomas Bernard + * (c) 2012-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -201,10 +201,16 @@ int add_pinhole(const char * ifname, { int uid; struct ip6t_entry * e; + struct ip6t_entry * tmp; struct ip6t_entry_match *match = NULL; struct ip6t_entry_target *target = NULL; e = calloc(1, sizeof(struct ip6t_entry)); + if(!e) { + syslog(LOG_ERR, "%s: calloc(%d) failed", + "add_pinhole", (int)sizeof(struct ip6t_entry)); + return -1; + } e->ipv6.proto = proto; if (proto) e->ipv6.flags |= IP6T_F_PROTO; @@ -223,9 +229,17 @@ int add_pinhole(const char * ifname, match = new_match(proto, rem_port, int_port); target = get_accept_target(); - e = realloc(e, sizeof(struct ip6t_entry) + tmp = realloc(e, sizeof(struct ip6t_entry) + match->u.match_size + target->u.target_size); + if(!tmp) { + syslog(LOG_ERR, "%s: realloc(%d) failed", + "add_pinhole", (int)(sizeof(struct ip6t_entry) + match->u.match_size + target->u.target_size)); + free(e); + free(match); + free(target); + return -1; + } memcpy(e->elems, match, match->u.match_size); memcpy(e->elems + match->u.match_size, target, target->u.target_size); e->target_offset = sizeof(struct ip6t_entry) diff --git a/miniupnpd/pf/obsdrdr.c b/miniupnpd/pf/obsdrdr.c index c4842fe..7c6799b 100644 --- a/miniupnpd/pf/obsdrdr.c +++ b/miniupnpd/pf/obsdrdr.c @@ -1,7 +1,7 @@ -/* $Id: obsdrdr.c,v 1.82 2014/04/15 23:15:25 nanard Exp $ */ +/* $Id: obsdrdr.c,v 1.84 2015/02/08 08:55:55 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2014 Thomas Bernard + * (c) 2006-2015 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -959,14 +959,17 @@ get_portmappings_in_range(unsigned short startport, unsigned short endport, if(*number >= capacity) { /* need to increase the capacity of the array */ + unsigned short * tmp; capacity += 128; - array = realloc(array, sizeof(unsigned short)*capacity); - if(!array) + tmp = realloc(array, sizeof(unsigned short)*capacity); + if(!tmp) { syslog(LOG_ERR, "get_portmappings_in_range() : realloc(%lu) error", sizeof(unsigned short)*capacity); *number = 0; + free(array); return NULL; } + array = tmp; } array[*number] = eport; (*number)++;