[gupnp] service: Check subscribtion target address



commit f943904e2d7f21601337b90058faf74b49c02796
Author: Jens Georg <mail jensge org>
Date:   Tue Jun 16 23:04:25 2020 +0200

    service: Check subscribtion target address
    
    It should not leave "our network segment". Mitigation for
    CVE-2020-12695 and required in UDA 2.0

 libgupnp/gupnp-context-private.h |  3 +++
 libgupnp/gupnp-context.c         | 26 ++++++++++++++++++++++++++
 libgupnp/gupnp-service.c         | 22 ++++++++++++++++------
 meson.build                      |  2 +-
 4 files changed, 46 insertions(+), 7 deletions(-)
---
diff --git a/libgupnp/gupnp-context-private.h b/libgupnp/gupnp-context-private.h
index ed39300..6aa1acd 100644
--- a/libgupnp/gupnp-context-private.h
+++ b/libgupnp/gupnp-context-private.h
@@ -40,6 +40,9 @@ 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 --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c
index 00e7abf..513edc4 100644
--- a/libgupnp/gupnp-context.c
+++ b/libgupnp/gupnp-context.c
@@ -1689,3 +1689,29 @@ gupnp_context_rewrite_uri_to_uri (GUPnPContext *context, const char *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 --git a/libgupnp/gupnp-service.c b/libgupnp/gupnp-service.c
index 47feab9..e6664d5 100644
--- a/libgupnp/gupnp-service.c
+++ b/libgupnp/gupnp-service.c
@@ -1192,14 +1192,24 @@ add_subscription_callback (GUPnPContext *context,
                            GList *list,
                            const char *callback)
 {
-    SoupURI *local_uri = NULL;
+            SoupURI *local_uri = NULL;
+            const char *host = NULL;
 
-    local_uri = gupnp_context_rewrite_uri_to_uri (context, callback);
-    if (local_uri != NULL) {
-        return g_list_append (list, local_uri);
-    }
+            local_uri = gupnp_context_rewrite_uri_to_uri (context, callback);
+            if (local_uri == NULL)
+                        return list;
 
-    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 */
diff --git a/meson.build b/meson.build
index eb3c82d..28c40b2 100644
--- a/meson.build
+++ b/meson.build
@@ -23,7 +23,7 @@ dependencies = [
     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')
 ]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]