diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2004-10-27 09:39:50 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2004-10-27 09:39:50 +0000 |
commit | 8e2c9792e923c95a4d353cbc0bb1146413b60168 (patch) | |
tree | 56ec6c65ae156086105bc87f73401c887f6f53fb | |
parent | 95ddcd326694de324a41a73d407d72604dd746d1 (diff) | |
download | libxml2-8e2c9792e923c95a4d353cbc0bb1146413b60168.tar.gz |
second part of the security fix for xmlNanoFTPConnect() and
* nanoftp.c nanohttp.c: second part of the security fix for
xmlNanoFTPConnect() and xmlNanoHTTPConnectHost().
Daniel
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | nanoftp.c | 38 | ||||
-rw-r--r-- | nanohttp.c | 18 |
3 files changed, 46 insertions, 15 deletions
@@ -1,3 +1,8 @@ +Wed Oct 27 11:44:35 CEST 2004 Daniel Veillard <daniel@veillard.com> + + * nanoftp.c nanohttp.c: second part of the security fix for + xmlNanoFTPConnect() and xmlNanoHTTPConnectHost(). + Tue Oct 26 23:57:02 CEST 2004 Daniel Veillard <daniel@veillard.com> * nanoftp.c: applied fixes for a couple of potential security problems @@ -1106,22 +1106,25 @@ xmlNanoFTPConnect(void *ctx) { if (!tmp) { if (result) freeaddrinfo (result); + __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed"); return (-1); } + if (tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) { + __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch"); + return (-1); + } + if (tmp->ai_family == AF_INET6) { + memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen); + ((struct sockaddr_in6 *) &ctxt->ftpAddr)->sin6_port = htons (port); + ctxt->controlFd = socket (AF_INET6, SOCK_STREAM, 0); + } else { - if (tmp->ai_family == AF_INET6) { - memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen); - ((struct sockaddr_in6 *) &ctxt->ftpAddr)->sin6_port = htons (port); - ctxt->controlFd = socket (AF_INET6, SOCK_STREAM, 0); - } - else { - memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen); - ((struct sockaddr_in *) &ctxt->ftpAddr)->sin_port = htons (port); - ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0); - } - addrlen = tmp->ai_addrlen; - freeaddrinfo (result); + memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen); + ((struct sockaddr_in *) &ctxt->ftpAddr)->sin_port = htons (port); + ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0); } + addrlen = tmp->ai_addrlen; + freeaddrinfo (result); } else #endif @@ -1134,10 +1137,15 @@ xmlNanoFTPConnect(void *ctx) { __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname failed"); return (-1); } + if (hp->h_length > + sizeof(((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr)) { + __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch"); + return (-1); + } - /* - * Prepare the socket - */ + /* + * Prepare the socket + */ ((struct sockaddr_in *)&ctxt->ftpAddr)->sin_family = AF_INET; memcpy (&((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr, hp->h_addr_list[0], hp->h_length); @@ -1072,11 +1072,21 @@ xmlNanoHTTPConnectHost(const char *host, int port) for (res = result; res; res = res->ai_next) { if (res->ai_family == AF_INET || res->ai_family == AF_INET6) { if (res->ai_family == AF_INET6) { + if (res->ai_addrlen > sizeof(sockin6)) { + __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); + freeaddrinfo (result); + return (-1); + } memcpy (&sockin6, res->ai_addr, res->ai_addrlen); sockin6.sin6_port = htons (port); addr = (struct sockaddr *)&sockin6; } else { + if (res->ai_addrlen > sizeof(sockin)) { + __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); + freeaddrinfo (result); + return (-1); + } memcpy (&sockin, res->ai_addr, res->ai_addrlen); sockin.sin_port = htons (port); addr = (struct sockaddr *)&sockin; @@ -1141,6 +1151,10 @@ xmlNanoHTTPConnectHost(const char *host, int port) for (i = 0; h->h_addr_list[i]; i++) { if (h->h_addrtype == AF_INET) { /* A records (IPv4) */ + if ((unsigned int) h->h_length > sizeof(ia)) { + __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); + return (-1); + } memcpy (&ia, h->h_addr_list[i], h->h_length); sockin.sin_family = h->h_addrtype; sockin.sin_addr = ia; @@ -1149,6 +1163,10 @@ xmlNanoHTTPConnectHost(const char *host, int port) #ifdef SUPPORT_IP6 } else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) { /* AAAA records (IPv6) */ + if ((unsigned int) h->h_length > sizeof(ia6)) { + __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); + return (-1); + } memcpy (&ia6, h->h_addr_list[i], h->h_length); sockin6.sin6_family = h->h_addrtype; sockin6.sin6_addr = ia6; |