Hello community, here is the log from the commit of package gupnp for openSUSE:Factory checked in at 2020-06-29 21:14:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gupnp (Old) and /work/SRC/openSUSE:Factory/.gupnp.new.3060 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gupnp" Mon Jun 29 21:14:47 2020 rev:62 rq:817299 version:1.2.3 Changes: -------- --- /work/SRC/openSUSE:Factory/gupnp/gupnp.changes 2020-01-08 19:32:14.792594678 +0100 +++ /work/SRC/openSUSE:Factory/.gupnp.new.3060/gupnp.changes 2020-06-29 21:14:55.969146744 +0200 @@ -1,0 +2,10 @@ +Tue Jun 23 07:49:08 UTC 2020 - Paolo Stivanin <[email protected]> + +- Update to version 1.2.3: + + Requires GSSDP 1.2.3 + + Always build the gupnp-binding-tool manpage + + Fix static linking issue caused by libguul subproject + + Add mitigations for CVE-2020-12695 + + Implement UDA 2.0 April 17 2020 Addendum + +------------------------------------------------------------------- Old: ---- gupnp-1.2.2.tar.xz New: ---- gupnp-1.2.3.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gupnp.spec ++++++ --- /var/tmp/diff_new_pack.ZHDoYn/_old 2020-06-29 21:14:56.597148687 +0200 +++ /var/tmp/diff_new_pack.ZHDoYn/_new 2020-06-29 21:14:56.597148687 +0200 @@ -21,7 +21,7 @@ %define sover 1.2 Name: gupnp -Version: 1.2.2 +Version: 1.2.3 Release: 0 Summary: Implementation of the UPnP specification License: LGPL-2.0-or-later ++++++ gupnp-1.2.2.tar.xz -> gupnp-1.2.3.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/.editorconfig new/gupnp-1.2.3/.editorconfig --- old/gupnp-1.2.2/.editorconfig 1970-01-01 01:00:00.000000000 +0100 +++ new/gupnp-1.2.3/.editorconfig 2020-06-23 00:12:01.003525000 +0200 @@ -0,0 +1,13 @@ +# https://editorconfig.org + +[*] +end_of_line = lf +insert_final_newline = true + +[*.{c,h}] +indent_style = space +indent_size = 8 + +[*.xml] +indent_style = space +indent_size = 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/NEWS new/gupnp-1.2.3/NEWS --- old/gupnp-1.2.2/NEWS 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/NEWS 2020-06-23 00:12:01.003525000 +0200 @@ -1,3 +1,24 @@ +1.2.3 +===== +- Attention: Requires GSSDP 1.2.3! +- Always build the gupnp-binding-tool manpage +- Fix meson build on Windows +- Fix context creation for tests across different platforms +- Fix static linking issue caused by libguul subproject +- Add mitigations for CVE-2020-12695 (CallStranger) +- Implement UDA 2.0 April 17 2020 Addendum (Patial fix for CVE-2020-12695) + +Bugs fixed in this release: + - https://gitlab.gnome.org/GNOME/gupnp/issues/15 + - https://gitlab.gnome.org/GNOME/gupnp/issues/16 + +All contributors to this release: + - Jens Georg <[email protected]> + - soiamsoNG <[email protected]> + - Peter Seiderer <[email protected]> + - Jan-Michael Brummer <[email protected]> + - Mart Raudsepp <[email protected]> + 1.2.2 ===== - Fix macOS dylib versioning diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/doc/meson.build new/gupnp-1.2.3/doc/meson.build --- old/gupnp-1.2.2/doc/meson.build 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/doc/meson.build 2020-06-23 00:12:01.007525000 +0200 @@ -4,6 +4,7 @@ output: 'version.xml', configuration: entities) +if get_option('gtk_doc') gnome.gtkdoc('gupnp', main_xml : 'gupnp-docs.xml', src_dir : [join_paths(meson.source_root(), 'libgupnp'), @@ -26,6 +27,7 @@ 'gupnp-types-private.h' ], install : true) +endif xsltproc = find_program('xsltproc', required: false) if xsltproc.found() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/libgupnp/gupnp-context-private.h new/gupnp-1.2.3/libgupnp/gupnp-context-private.h --- old/gupnp-1.2.2/libgupnp/gupnp-context-private.h 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/libgupnp/gupnp-context-private.h 2020-06-23 00:12:01.007525000 +0200 @@ -36,6 +36,13 @@ const char *path, AclServerHandler *data); +G_GNUC_INTERNAL SoupURI * +gupnp_context_rewrite_uri_to_uri (GUPnPContext *context, + const char *uri); + +G_GNUC_INTERNAL gboolean +gupnp_context_ip_is_ours (GUPnPContext *context, const char *address); + G_END_DECLS #endif /* GUPNP_CONTEXT_PRIVATE_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/libgupnp/gupnp-context.c new/gupnp-1.2.3/libgupnp/gupnp-context.c --- old/gupnp-1.2.2/libgupnp/gupnp-context.c 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/libgupnp/gupnp-context.c 2020-06-23 00:12:01.011525000 +0200 @@ -1618,21 +1618,59 @@ * the zone index appended to the IP address. * * Returns: A re-written version of the @uri if the context is on a link-local - * IPv6 address, a copy of the @uri otherwise. + * IPv6 address, a copy of the @uri otherwise or %NULL if @uri was invalid * * Since: 1.1.1 */ char * -gupnp_context_rewrite_uri (GUPnPContext *context, const char *plain_uri) +gupnp_context_rewrite_uri (GUPnPContext *context, const char *uri) +{ + SoupURI *soup_uri = NULL; + char *retval = NULL; + + soup_uri = gupnp_context_rewrite_uri_to_uri (context, uri); + if (soup_uri == NULL) { + // We already issued a warning above, so just return + return NULL; + } + + retval = soup_uri_to_string (soup_uri, FALSE); + soup_uri_free (soup_uri); + + return retval; +} + +/** + * gupnp_context_rewrite_uri_to_uri: + * @context: a #GUPnPContext + * @uri: an uri to rewrite if necessary + * + * Utility function to re-write an uri to the IPv6 link-local form which has + * the zone index appended to the IP address. + * + * Returns: A re-written version of the @uri if the context is on a link-local + * IPv6 address or @uri converted to a #SoupURI or %NULL if @uri is invalid + * + * Since: 1.2.3 + * Stability: Private + */ +SoupURI * +gupnp_context_rewrite_uri_to_uri (GUPnPContext *context, const char *uri) { const char *host = NULL; - SoupURI *uri = NULL; + SoupURI *soup_uri = NULL; GInetAddress *addr = NULL; - char *retval = NULL; int index = -1; - uri = soup_uri_new (plain_uri); - host = soup_uri_get_host (uri); + soup_uri = soup_uri_new (uri); + + if (soup_uri == NULL) { + g_warning ("Invalid call-back url: %s", uri); + + return NULL; + } + + host = soup_uri_get_host (soup_uri); addr = g_inet_address_new_from_string (host); index = gssdp_client_get_index (GSSDP_CLIENT (context)); @@ -1643,13 +1681,37 @@ new_host = g_strdup_printf ("%s%%%d", host, index); - soup_uri_set_host (uri, new_host); + soup_uri_set_host (soup_uri, new_host); g_free (new_host); } g_object_unref (addr); - retval = soup_uri_to_string (uri, FALSE); - soup_uri_free (uri); + + return soup_uri; +} + +gboolean +gupnp_context_ip_is_ours (GUPnPContext *context, const char *address) +{ + // TODO: Could easily be in GSSDPClient, which does something similar + gboolean retval = FALSE; + GInetAddress *addr = NULL; + GInetAddressMask *mask = NULL; + + addr = g_inet_address_new_from_string (address); + + // Link-local addresses are reachable + if (g_inet_address_get_is_link_local (addr)) { + retval = TRUE; + goto out; + } + + mask = gssdp_client_get_address_mask (GSSDP_CLIENT (context)); + retval = g_inet_address_mask_matches (mask, addr); + g_object_unref (mask); + +out: + g_object_unref (addr); return retval; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/libgupnp/gupnp-service-info.h new/gupnp-1.2.3/libgupnp/gupnp-service-info.h --- old/gupnp-1.2.2/libgupnp/gupnp-service-info.h 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/libgupnp/gupnp-service-info.h 2020-06-23 00:12:01.015525000 +0200 @@ -52,8 +52,8 @@ /** * GUPnPServiceIntrospectionCallback: * @info: The #GUPnPServiceInfo introspection was requested for - * @introspection: The new #GUPnPServiceIntrospection object, or NULL - * @error: The #GError that occurred, or NULL + * @introspection: (nullable): The new #GUPnPServiceIntrospection object, or NULL + * @error: (nullable): The #GError that occurred, or NULL * @user_data: User data * * Callback notifying that @introspection for @info has been obtained. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/libgupnp/gupnp-service.c new/gupnp-1.2.3/libgupnp/gupnp-service.c --- old/gupnp-1.2.2/libgupnp/gupnp-service.c 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/libgupnp/gupnp-service.c 2020-06-23 00:12:01.015525000 +0200 @@ -190,7 +190,7 @@ } /* Further cleanup */ - g_list_free_full (data->callbacks, g_free); + g_list_free_full (data->callbacks, (GDestroyNotify) soup_uri_free); g_free (data->sid); @@ -1187,6 +1187,31 @@ g_free (mem); } +static GList * +add_subscription_callback (GUPnPContext *context, + GList *list, + const char *callback) +{ + SoupURI *local_uri = NULL; + const char *host = NULL; + + local_uri = gupnp_context_rewrite_uri_to_uri (context, callback); + if (local_uri == NULL) { + return list; + } + + + host = soup_uri_get_host (local_uri); + // CVE-2020-12695: Ignore subscription call-backs that are not "in + // our network segment" + if (gupnp_context_ip_is_ours (context, host)) { + return g_list_append (list, local_uri); + } else { + g_warning ("%s is not in our network; ignoring", callback); + } + + return list; +} /* Subscription request */ static void @@ -1195,9 +1220,10 @@ const char *callback) { SubscriptionData *data; - char *start, *end, *uri; + char *start, *end; GUPnPServicePrivate *priv; GUPnPContext *context; + int callbacks = 0; priv = gupnp_service_get_instance_private (service); context = gupnp_service_info_get_context @@ -1207,7 +1233,10 @@ /* Parse callback list */ start = (char *) callback; - while ((start = strchr (start, '<'))) { + + // Arbitrarily limit the list of callbacks to 6 + // Part of CVE-2020-12695 mitigation + while (callbacks < 6 && (start = strchr (start, '<'))) { start += 1; if (!start || !*start) break; @@ -1216,17 +1245,24 @@ if (!end || !*end) break; - if (strncmp (start, "http://", strlen ("http://")) == 0) { - char *local_uri; - - uri = g_strndup (start, end - start); - local_uri = gupnp_context_rewrite_uri (context, uri); - g_free (uri); - - data->callbacks = g_list_append (data->callbacks, local_uri); + *end = '\0'; + if (g_str_has_prefix (start, "http://")) { + // DLNA 7.3.2.24.4 - URIs shall not exceed 256 bytes + // Also one part of CVE-2020-12695 mitigation - limit URI length + // UPnP does not impose any restrictions here + if (strlen (start) <= 256) { + data->callbacks = add_subscription_callback (context, + data->callbacks, + start); + } else { + g_warning ("Subscription URI exceeds recommended length " + "of 256 bytes, skipping"); + } } + *end = '>'; start = end; + callbacks++; } if (!data->callbacks) { @@ -1945,32 +1981,27 @@ } /* Send notification @user_data to subscriber @value */ -static void -notify_subscriber (G_GNUC_UNUSED gpointer key, - gpointer value, - gpointer user_data) -{ - SubscriptionData *data; - const char *property_set; - char *tmp; - SoupMessage *msg; - SoupSession *session; - - data = value; - property_set = user_data; - - /* Subscriber called unsubscribe */ - if (subscription_data_can_delete (data)) - return; - - /* Create message */ - msg = soup_message_new (GENA_METHOD_NOTIFY, data->callbacks->data); - if (!msg) { - g_warning ("Invalid callback URL: %s", - (char *) data->callbacks->data); - - return; - } + static void + notify_subscriber (G_GNUC_UNUSED gpointer key, + gpointer value, + gpointer user_data) + { + SubscriptionData *data; + const char *property_set; + char *tmp; + SoupMessage *msg; + SoupSession *session; + + data = value; + property_set = user_data; + + /* Subscriber called unsubscribe */ + if (subscription_data_can_delete (data)) + return; + + /* Create message */ + msg = soup_message_new_from_uri (GENA_METHOD_NOTIFY, + data->callbacks->data); soup_message_headers_append (msg->request_headers, "NT", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/libgupnp/meson.build new/gupnp-1.2.3/libgupnp/meson.build --- old/gupnp-1.2.2/libgupnp/meson.build 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/libgupnp/meson.build 2020-06-23 00:12:01.019525000 +0200 @@ -4,8 +4,8 @@ if host_machine.system() == 'windows' context_manager_impl += 'gupnp-windows-context-manager.c' - system_deps += cc.find_library('ws2_32', required : 'true') - system_deps += cc.find_library('iphlpapi', required : 'true') + system_deps += cc.find_library('ws2_32', required : true) + system_deps += cc.find_library('iphlpapi', required : true) else if ifaddrs_available context_manager_impl += 'gupnp-unix-context-manager.c' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/meson.build new/gupnp-1.2.3/meson.build --- old/gupnp-1.2.2/meson.build 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/meson.build 2020-06-23 00:12:01.019525000 +0200 @@ -1,4 +1,4 @@ -project('gupnp', 'c', version : '1.2.2', meson_version : '>= 0.48.0') +project('gupnp', 'c', version : '1.2.3', meson_version : '>= 0.48.0') gnome = import('gnome') pkg = import('pkgconfig') @@ -23,7 +23,7 @@ dependency('gio-2.0', version : '>= 2.58'), dependency('gmodule-2.0', version : '>= 2.44'), dependency('gobject-2.0', version : '>= 2.44'), - dependency('gssdp-1.2', version : '>= 1.1.3'), + dependency('gssdp-1.2', version : '>= 1.2.3'), dependency('libsoup-2.4', version : '>= 2.48.0'), dependency('libxml-2.0') ] @@ -31,15 +31,12 @@ subdir('libgupnp') subdir('tests') subdir('tools') +subdir('doc') if get_option('vapi') and get_option('introspection') subdir('vala') endif -if get_option('gtk_doc') - subdir('doc') -endif - if get_option('examples') subdir('examples') endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/subprojects/guul/meson.build new/gupnp-1.2.3/subprojects/guul/meson.build --- old/gupnp-1.2.2/subprojects/guul/meson.build 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/subprojects/guul/meson.build 2020-06-23 00:12:01.019525000 +0200 @@ -29,5 +29,6 @@ guul = declare_dependency ( link_with : guul_lib, + dependencies : dependencies, include_directories: include_directories('.') ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/tests/gtest/test-bugs.c new/gupnp-1.2.3/tests/gtest/test-bugs.c --- old/gupnp-1.2.2/tests/gtest/test-bugs.c 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/tests/gtest/test-bugs.c 2020-06-23 00:12:01.019525000 +0200 @@ -26,6 +26,16 @@ #include <libgupnp/gupnp.h> #include <libgupnp/gupnp-service-private.h> +static GUPnPContext * +create_context (guint16 port, GError **error) { + return GUPNP_CONTEXT (g_initable_new (GUPNP_TYPE_CONTEXT, + NULL, + error, + "host-ip", "127.0.0.1", + "msearch-port", port, + NULL)); +} + typedef struct _TestBgo678701Service { GUPnPServiceProxy parent_instance; }TestBgo678701Service; @@ -195,7 +205,7 @@ data.loop = g_main_loop_new (NULL, FALSE); - context = gupnp_context_new ("lo", 0, &error); + context = create_context (0, &error); g_assert_no_error (error); g_assert (context != NULL); @@ -264,7 +274,7 @@ data.loop = g_main_loop_new (NULL, FALSE); - context = gupnp_context_new ("lo", 0, &error); + context = create_context (0, &error); g_assert_no_error (error); g_assert (context != NULL); @@ -321,7 +331,7 @@ data.loop = g_main_loop_new (NULL, FALSE); - context = gupnp_context_new ("lo", 0, &error); + context = create_context (0, &error); g_assert_no_error (error); g_assert (context != NULL); @@ -380,7 +390,7 @@ char *icon; int width; - context = gupnp_context_new ("lo", 0, &error); + context = create_context (0, &error); g_assert_no_error (error); g_assert (context != NULL); @@ -441,7 +451,7 @@ GUPnPControlPoint *cp = NULL; GError *error = NULL; - context = gupnp_context_new ("lo", 0, &error); + context = create_context (0, &error); g_assert_no_error (error); g_assert (context != NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gupnp-1.2.2/tests/gtest/test-context.c new/gupnp-1.2.3/tests/gtest/test-context.c --- old/gupnp-1.2.2/tests/gtest/test-context.c 2020-01-02 13:07:01.000000000 +0100 +++ new/gupnp-1.2.3/tests/gtest/test-context.c 2020-06-23 00:12:01.019525000 +0200 @@ -28,6 +28,16 @@ #include <libsoup/soup.h> #include "libgupnp/gupnp.h" +static GUPnPContext * +create_context (guint16 port, GError **error) { + return GUPNP_CONTEXT (g_initable_new (GUPNP_TYPE_CONTEXT, + NULL, + error, + "host-ip", "127.0.0.1", + "msearch-port", port, + NULL)); +} + static void on_message_finished (G_GNUC_UNUSED SoupSession *session, G_GNUC_UNUSED SoupMessage *message, @@ -134,9 +144,7 @@ g_assert (error == NULL); file_length = g_mapped_file_get_length (file); - context = gupnp_context_new ("lo", - 0, - &error); + context = create_context (0, &error); g_assert (context != NULL); g_assert (error == NULL); port = gupnp_context_get_port (context);
