[126547] trunk/dports/devel/libupnp

ctreleaven at macports.org ctreleaven at macports.org
Sat Oct 11 18:01:20 PDT 2014


Revision: 126547
          https://trac.macports.org/changeset/126547
Author:   ctreleaven at macports.org
Date:     2014-10-11 18:01:19 -0700 (Sat, 11 Oct 2014)
Log Message:
-----------
libupnp: update to 1.6.19, claim maintainership, add security-related patches, fixes #42647

Modified Paths:
--------------
    trunk/dports/devel/libupnp/Portfile

Added Paths:
-----------
    trunk/dports/devel/libupnp/files/
    trunk/dports/devel/libupnp/files/patch-Fix-getaddrinfo-loop.diff
    trunk/dports/devel/libupnp/files/patch-Fix-resolve_rel_url.diff
    trunk/dports/devel/libupnp/files/patch-Fix_broken_strncat.diff
    trunk/dports/devel/libupnp/files/patch-directly_use_strdup.diff

Modified: trunk/dports/devel/libupnp/Portfile
===================================================================
--- trunk/dports/devel/libupnp/Portfile	2014-10-12 00:38:36 UTC (rev 126546)
+++ trunk/dports/devel/libupnp/Portfile	2014-10-12 01:01:19 UTC (rev 126547)
@@ -4,11 +4,11 @@
 PortSystem 1.0
 
 name                libupnp
-version             1.6.6
+version             1.6.19
 categories          devel
 platforms           darwin
-maintainers         nomaintainer
-description         A portable open source UPnP development kit
+maintainers         ctreleaven openmaintainer
+description         portable open source UPnP development kit
 long_description \
     The portable SDK for UPnP(tm) Devices (libupnp) provides developers with \
     an API and open source code for building control points, devices, and \
@@ -18,10 +18,20 @@
 
 homepage            http://pupnp.sourceforge.net
 master_sites        sourceforge:pupnp
+# tried to Avoid Redirects but uri contains %20 character ?!?
 use_bzip2           yes
-checksums           md5 8918dcf7428cd119d0c8275765ff2833 \
-                    sha1 24c2c349cb52ed3d62121fbdae205c8d9dc0f5fa \
-                    rmd160 25ff0390793cfa48cca32a335b4d633283b1fe64
+checksums           md5     ee16e5d33a3ea7506f38d71facc057dd \
+                    sha1    ee9e16ff42808521b62b7fc664fc9cba479ede88 \
+                    rmd160  9879bc7e2e31b50b36ca752c70a00b3abc6de23f
 
+# Following 4 patches fix security faults - http://sourceforge.net/p/pupnp/bugs/122/
+patchfiles         patch-Fix_broken_strncat.diff \
+                   patch-directly_use_strdup.diff \
+                   patch-Fix-getaddrinfo-loop.diff \
+                   patch-Fix-resolve_rel_url.diff
+
+configure.args-append \
+                    --enable-ipv6
+
 livecheck.url       http://sourceforge.net/projects/pupnp/files/pupnp/
 livecheck.regex    "title=\\\"libUPnP (\\d+(?:\\.\\d+)*)"

Added: trunk/dports/devel/libupnp/files/patch-Fix-getaddrinfo-loop.diff
===================================================================
--- trunk/dports/devel/libupnp/files/patch-Fix-getaddrinfo-loop.diff	                        (rev 0)
+++ trunk/dports/devel/libupnp/files/patch-Fix-getaddrinfo-loop.diff	2014-10-12 01:01:19 UTC (rev 126547)
@@ -0,0 +1,47 @@
+>From 2dd10ef70c1cb36748b04c5d9425e4b511ece969 Mon Sep 17 00:00:00 2001
+From: Fabrice Fontaine <fabrice.fontaine at orange.com>
+Date: Wed, 14 Mar 2012 22:37:10 +0100
+Subject: [PATCH 1/6] Fix getaddrinfo() loop
+
+Commit b116d10f did the following change:
+    Use switch, int and sa_family_t with AF_INET in uri.c.
+
+This breaks when getaddrinfo() only returns a single record, as in that
+case the "break" only exits the switch statement and the loop-step
+"res=res->ai_next" is still executed. After that "res == NULL" is
+wrongly interpreted as not having found an AF_INET or AF_INET6 address.
+---
+ upnp/src/genlib/net/uri/uri.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/upnp/src/genlib/net/uri/uri.c b/upnp/src/genlib/net/uri/uri.c
+index dff0c96..96b2a32 100644
+--- upnp/src/genlib/net/uri/uri.c
++++ upnp/src/genlib/net/uri/uri.c
+@@ -387,7 +387,7 @@ static int parse_hostport(
+ 
+ 			ret = getaddrinfo(srvname, NULL, &hints, &res0);
+ 			if (ret == 0) {
+-				for (res = res0; res && !ret; res = res->ai_next) {
++				for (res = res0; res; res = res->ai_next) {
+ 					switch (res->ai_family) {
+ 					case AF_INET:
+ 					case AF_INET6:
+@@ -395,12 +395,10 @@ static int parse_hostport(
+ 						memcpy(&out->IPaddress,
+ 						       res->ai_addr,
+ 						       res->ai_addrlen);
+-						ret=1;
+-						break;
+-					default:
+-						break;
++						goto found;
+ 					}
+ 				}
++found:
+ 				freeaddrinfo(res0);
+ 				if (res == NULL)
+ 					/* Didn't find an AF_INET or AF_INET6 address. */
+-- 
+2.0.0.rc0
+

Added: trunk/dports/devel/libupnp/files/patch-Fix-resolve_rel_url.diff
===================================================================
--- trunk/dports/devel/libupnp/files/patch-Fix-resolve_rel_url.diff	                        (rev 0)
+++ trunk/dports/devel/libupnp/files/patch-Fix-resolve_rel_url.diff	2014-10-12 01:01:19 UTC (rev 126547)
@@ -0,0 +1,239 @@
+>From 2869c6f33d7333bed7ec39b201a1d9171c4fc0b2 Mon Sep 17 00:00:00 2001
+From: Philipp Matthias Hahn <pmhahn at pmhahn.de>
+Date: Thu, 1 May 2014 10:41:20 +0200
+Subject: [PATCH 4/6] Fix resolve_rel_url()
+
+This reworks commit 0edaf3361db01425cae0daee7dc3f6039f381a17, which
+broke resolving relative url, where the relative URL is shorter than the
+absolute URL:
+    "http://127.0.0.1:6544/getDeviceDesc" + "CDS_Event"
+    Wrong: "http://127.0.0.1:6544/CDS_EventDesc"
+    Right: "http://127.0.0.1:6544/CDS_Event"
+
+While reviewing that commit, improve code by:
+1. Move the simple cases to the beginning of the function.
+2. Keep track of the remaining target buffer size.
+3. Fix URI concatenation with queries.
+4. Fix URI concatenation with fragments.
+---
+ upnp/src/genlib/net/uri/uri.c | 192 +++++++++++++++++++++---------------------
+ 1 file changed, 95 insertions(+), 97 deletions(-)
+
+diff --git a/upnp/src/genlib/net/uri/uri.c b/upnp/src/genlib/net/uri/uri.c
+index 96b2a32..827693f 100644
+--- upnp/src/genlib/net/uri/uri.c
++++ upnp/src/genlib/net/uri/uri.c
+@@ -580,115 +580,113 @@ char *resolve_rel_url(char *base_url, char *rel_url)
+ {
+     uri_type base;
+     uri_type rel;
++    int rv;
+ 
+-    size_t i = (size_t)0;
+-    char *finger = NULL;
+-
+-    char *last_slash = NULL;
+-
+-    char *out = NULL;
+-
+-    if( base_url && rel_url ) {
+-        out =
+-            ( char * )malloc( strlen( base_url ) + strlen( rel_url ) + (size_t)2 );
+-    } else {
+-        if( rel_url )
+-            return strdup( rel_url );
+-        else
++    if (!base_url) {
++        if (!rel_url)
+             return NULL;
++        return strdup(rel_url);
+     }
+ 
+-    if( out == NULL ) {
++    size_t len_rel = strlen(rel_url);
++    if (parse_uri(rel_url, len_rel, &rel) != HTTP_SUCCESS)
+         return NULL;
+-    }
+-    memset( out, 0, strlen( base_url ) + strlen( rel_url ) + (size_t)2 );
++    if (rel.type == (enum uriType)ABSOLUTE)
++        return strdup(rel_url);
+ 
+-    if( ( parse_uri( rel_url, strlen( rel_url ), &rel ) ) == HTTP_SUCCESS ) {
+-
+-        if( rel.type == ( enum uriType) ABSOLUTE ) {
+-
+-            strncpy( out, rel_url, strlen ( rel_url ) );
+-        } else {
++    size_t len_base = strlen(base_url);
++    if ((parse_uri(base_url, len_base, &base) != HTTP_SUCCESS)
++            || (base.type != (enum uriType)ABSOLUTE))
++        return NULL;
++    if (len_rel == (size_t)0)
++        return strdup(base_url);
+ 
+-            if( ( parse_uri( base_url, strlen( base_url ), &base ) ==
+-                  HTTP_SUCCESS )
+-                && ( base.type == ( enum uriType ) ABSOLUTE ) ) {
++    size_t len = len_base + len_rel + (size_t)2;
++    char *out = (char *)malloc(len);
++    if (out == NULL)
++        return NULL;
++    memset(out, 0, len);
++    char *out_finger = out;
++
++    /* scheme */
++    rv = snprintf(out_finger, len, "%.*s:", (int)base.scheme.size, base.scheme.buff);
++    if (rv < 0 || rv >= len)
++        goto error;
++    out_finger += rv;
++    len -= rv;
++
++    /* authority */
++    if (rel.hostport.text.size > (size_t)0) {
++        rv = snprintf(out_finger, len, "%s", rel_url);
++        if (rv < 0 || rv >= len)
++            goto error;
++        return out;
++    }
++    if (base.hostport.text.size > (size_t)0) {
++	rv = snprintf(out_finger, len, "//%.*s", (int)base.hostport.text.size, base.hostport.text.buff);
++	if (rv < 0 || rv >= len)
++	    goto error;
++	out_finger += rv;
++	len -= rv;
++    }
+ 
+-                if( strlen( rel_url ) == (size_t)0 ) {
+-                    strncpy( out, base_url, strlen ( base_url ) );
+-                } else {
+-                    char *out_finger = out;
+-                    assert( base.scheme.size + (size_t)1 /* ':' */ <= strlen ( base_url ) );
+-                    memcpy( out, base.scheme.buff, base.scheme.size );
+-                    out_finger += base.scheme.size;
+-                    ( *out_finger ) = ':';
+-                    out_finger++;
+-
+-                    if( rel.hostport.text.size > (size_t)0 ) {
+-                        snprintf( out_finger, strlen( rel_url ) + (size_t)1,
+-                                  "%s", rel_url );
+-                    } else {
+-                        if( base.hostport.text.size > (size_t)0 ) {
+-                            assert( base.scheme.size + (size_t)1
+-                                + base.hostport.text.size + (size_t)2 /* "//" */ <= strlen ( base_url ) );
+-                            memcpy( out_finger, "//", (size_t)2 );
+-                            out_finger += 2;
+-                            memcpy( out_finger, base.hostport.text.buff,
+-                                    base.hostport.text.size );
+-                            out_finger += base.hostport.text.size;
+-                        }
+-
+-                        if( rel.path_type == ( enum pathType ) ABS_PATH ) {
+-                            strncpy( out_finger, rel_url, strlen ( rel_url ) );
+-
+-                        } else {
+-                            char temp_path = '/';
+-
+-                            if( base.pathquery.size == (size_t)0 ) {
+-                                base.pathquery.size = (size_t)1;
+-                                base.pathquery.buff = &temp_path;
+-                            }
+-
+-                            assert( base.scheme.size + (size_t)1 + base.hostport.text.size + (size_t)2
+-                                + base.pathquery.size <= strlen ( base_url ) + (size_t)1 /* temp_path */);
+-                            finger = out_finger;
+-                            last_slash = finger;
+-                            i = (size_t)0;
+-                            while( ( i < base.pathquery.size ) &&
+-                                   ( base.pathquery.buff[i] != '?' ) ) {
+-                                ( *finger ) = base.pathquery.buff[i];
+-                                if( base.pathquery.buff[i] == '/' )
+-                                    last_slash = finger + 1;
+-                                i++;
+-                                finger++;
+-
+-                            }
+-                            strncpy( last_slash, rel_url, strlen ( rel_url ) );
+-                            if( remove_dots( out_finger,
+-                                             strlen( out_finger ) ) !=
+-                                UPNP_E_SUCCESS ) {
+-                                free(out);
+-                                /* free(rel_url); */
+-                                return NULL;
+-                            }
+-                        }
+-
+-                    }
+-                }
+-            } else {
+-                free(out);
+-                /* free(rel_url); */
+-                return NULL;
+-            }
+-        }
++    /* path */
++    char *path = out_finger;
++    if (rel.path_type == (enum pathType)ABS_PATH) {
++	rv = snprintf(out_finger, len, "%s", rel_url);
++    } else if (base.pathquery.size == (size_t)0) {
++	rv = snprintf(out_finger, len, "/%s", rel_url);
+     } else {
+-        free(out);
+-        /* free(rel_url); */          
+-        return NULL;
++	if (rel.pathquery.size == (size_t)0) {
++	    rv = snprintf(out_finger, len, "%.*s", (int)base.pathquery.size, base.pathquery.buff);
++	} else {
++	    if (len < base.pathquery.size)
++		goto error;
++	    size_t i = (size_t)0, prefix = (size_t)1;
++	    while (i < base.pathquery.size) {
++		out_finger[i] = base.pathquery.buff[i];
++		switch (base.pathquery.buff[i++]) {
++		    case '/':
++			prefix = i;
++			/* fall-through */
++		    default:
++			continue;
++		    case '?': /* query */
++			if (rel.pathquery.buff[0] == '?')
++			    prefix = --i;
++		}
++		break;
++	    }
++	    out_finger += prefix;
++	    len -= prefix;
++	    rv = snprintf(out_finger, len, "%.*s", (int)rel.pathquery.size, rel.pathquery.buff);
++	}
++	if (rv < 0 || rv >= len)
++	    goto error;
++	out_finger += rv;
++	len -= rv;
++
++	/* fragment */
++	if (rel.fragment.size > (size_t)0)
++	    rv = snprintf(out_finger, len, "#%.*s", (int)rel.fragment.size, rel.fragment.buff);
++	else if (base.fragment.size > (size_t)0)
++	    rv = snprintf(out_finger, len, "#%.*s", (int)base.fragment.size, base.fragment.buff);
++	else
++	    rv = 0;
+     }
++    if (rv < 0 || rv >= len)
++	goto error;
++    out_finger += rv;
++    len -= rv;
++
++    if (remove_dots(path, out_finger - path) != UPNP_E_SUCCESS)
++	goto error;
+ 
+-    /* free(rel_url); */
+     return out;
++
++error:
++    free(out);
++    return NULL;
+ }
+ 
+ 
+-- 
+2.0.0.rc0
+

Added: trunk/dports/devel/libupnp/files/patch-Fix_broken_strncat.diff
===================================================================
--- trunk/dports/devel/libupnp/files/patch-Fix_broken_strncat.diff	                        (rev 0)
+++ trunk/dports/devel/libupnp/files/patch-Fix_broken_strncat.diff	2014-10-12 01:01:19 UTC (rev 126547)
@@ -0,0 +1,29 @@
+Fix broken strncat(..., strlen())
+commit 0edaf3361db01425cae0daee7dc3f6039f381a17 replaced several
+malloc()+strcat() sequences with strncat() using strlen() on the
+*source* string.
+This is still vulnerable to overwrite the *target* buffer.
+While reviewing this commit change the code to directly use snprintf()
+for concatenating strings and check the length of the target buffer.
+Signed-off-by: Marcelo Roberto Jimenez <mroberto at users.sourceforge.net>
+(cherry picked from commit 848d66e69daf30d3b64db1450618cd819c370ad4)
+
+--- upnp/src/genlib/net/http/httpreadwrite.c
++++ upnp/src/genlib/net/http/httpreadwrite.c
+@@ -541,13 +541,12 @@
+ 					memset(Chunk_Header, 0,
+ 						sizeof(Chunk_Header));
+ 					rc = snprintf(Chunk_Header,
+-						sizeof(Chunk_Header) - strlen ("\r\n"),
+-						"%" PRIzx, num_read);
+-					if (rc < 0 || (unsigned int) rc >= sizeof(Chunk_Header) - strlen ("\r\n")) {
++						sizeof(Chunk_Header),
++						"%" PRIzx "\r\n", num_read);
++					if (rc < 0 || (unsigned int) rc >= sizeof(Chunk_Header)) {
+ 						RetVal = UPNP_E_INTERNAL_ERROR;
+ 						goto Cleanup_File;
+ 					}
+-					strncat(Chunk_Header, "\r\n", strlen ("\r\n"));
+ 					/* Copy the chunk size header  */
+ 					memcpy(file_buf - strlen(Chunk_Header),
+ 					       Chunk_Header,

Added: trunk/dports/devel/libupnp/files/patch-directly_use_strdup.diff
===================================================================
--- trunk/dports/devel/libupnp/files/patch-directly_use_strdup.diff	                        (rev 0)
+++ trunk/dports/devel/libupnp/files/patch-directly_use_strdup.diff	2014-10-12 01:01:19 UTC (rev 126547)
@@ -0,0 +1,120 @@
+Directly use strdup()
+commit 0edaf3361db01425cae0daee7dc3f6039f381a17 replaced several
+malloc()+strcpy() sequences with memset()+strncpy() using strlen().
+This doesn't improve security and introduced a bug URI handling.
+While reviewing this commit change the code to directly use strdup()
+instead of re-implementing it multiple times, as shortens the code and
+thus improves readability.
+Signed-off-by: Marcelo Roberto Jimenez <mroberto at users.sourceforge.net>
+(cherry picked from commit 04fb68432330c3a622161dda98dbe1b30eaa0927)
+
+--- upnp/src/gena/gena_device.c
++++ upnp/src/gena/gena_device.c
+@@ -480,24 +480,19 @@
+ 	}
+ 	*reference_count = 0;
+ 	
+-	UDN_copy = (char *)malloc(strlen(UDN) + 1);
++	UDN_copy = strdup(UDN);
+ 	if (UDN_copy == NULL) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+ 
+-	servId_copy = (char *)malloc(strlen(servId) + 1);
++	servId_copy = strdup(servId);
+ 	if (servId_copy == NULL) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+-
+-	memset(UDN_copy, 0, strlen(UDN) + 1);
+-	strncpy(UDN_copy, UDN, strlen(UDN));
+-	memset(servId_copy, 0, strlen(servId) + 1);
+-	strncpy(servId_copy, servId, strlen(servId));
+ 
+ 	HandleLock();
+ 
+@@ -639,24 +634,19 @@
+ 	}
+ 	*reference_count = 0;
+ 	
+-	UDN_copy = (char *)malloc(strlen(UDN) + 1);
++	UDN_copy = strdup(UDN);
+ 	if (UDN_copy == NULL) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+ 
+-	servId_copy = (char *)malloc(strlen(servId) + 1);
++	servId_copy = strdup(servId);
+ 	if( servId_copy == NULL ) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+-
+-	memset(UDN_copy, 0, strlen(UDN) + 1);
+-	strncpy(UDN_copy, UDN, strlen(UDN));
+-	memset(servId_copy, 0, strlen(servId) + 1);
+-	strncpy(servId_copy, servId, strlen(servId));
+ 
+ 	HandleLock();
+ 
+@@ -798,24 +788,19 @@
+ 	}
+ 	*reference_count = 0;
+ 	
+-	UDN_copy = (char *)malloc(strlen(UDN) + 1);
++	UDN_copy = strdup(UDN);
+ 	if (UDN_copy == NULL) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+ 
+-	servId_copy = (char *)malloc(strlen(servId) + 1);
++	servId_copy = strdup(servId);
+ 	if( servId_copy == NULL ) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+-
+-	memset(UDN_copy, 0, strlen(UDN) + 1);
+-	strncpy(UDN_copy, UDN, strlen(UDN));
+-	memset(servId_copy, 0, strlen(servId) + 1);
+-	strncpy(servId_copy, servId, strlen(servId));
+ 
+ 	propertySet = ixmlPrintNode((IXML_Node *)PropSet);
+ 	if (propertySet == NULL) {
+@@ -944,24 +929,19 @@
+ 	}
+ 	*reference_count = 0;
+ 	
+-	UDN_copy = (char *)malloc(strlen(UDN) + 1);
++	UDN_copy = strdup(UDN);
+ 	if (UDN_copy == NULL) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+ 
+-	servId_copy = (char *)malloc(strlen(servId) + 1);
++	servId_copy = strdup(servId);
+ 	if( servId_copy == NULL ) {
+ 		line = __LINE__;
+ 		ret = UPNP_E_OUTOF_MEMORY;
+ 		goto ExitFunction;
+ 	}
+-
+-	memset(UDN_copy, 0, strlen(UDN) + 1);
+-	strncpy(UDN_copy, UDN, strlen(UDN));
+-	memset(servId_copy, 0, strlen(servId) + 1);
+-	strncpy(servId_copy, servId, strlen(servId));
+ 
+ 	ret = GeneratePropertySet(VarNames, VarValues, var_count, &propertySet);
+ 	if (ret != XML_SUCCESS) {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20141011/bc9ed718/attachment-0001.html>


More information about the macports-changes mailing list