All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] wispr: Rename wispr_portal_list to wispr_portal_hash
@ 2022-08-01  8:00 Daniel Wagner
  2022-08-01  8:00 ` [PATCH 2/6] wispr: Ignore NULL proxy Daniel Wagner
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Daniel Wagner @ 2022-08-01  8:00 UTC (permalink / raw)
  To: connman; +Cc: Daniel Wagner

This data structure is a hash table, so replace the '_list' with
'_hash' to reduce the possibility for confusion.

Signed-off-by: Daniel Wagner <wagi@monom.org>
---
 src/wispr.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/wispr.c b/src/wispr.c
index 7d4a3f54b24b..9bd2a2ef1d5f 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -91,7 +91,7 @@ struct connman_wispr_portal {
 
 static bool wispr_portal_web_result(GWebResult *result, gpointer user_data);
 
-static GHashTable *wispr_portal_list = NULL;
+static GHashTable *wispr_portal_hash = NULL;
 
 static char *online_check_ipv4_url = NULL;
 static char *online_check_ipv6_url = NULL;
@@ -576,7 +576,7 @@ static void wispr_portal_browser_reply_cb(struct connman_service *service,
 	if (index < 0)
 		return;
 
-	wispr_portal = g_hash_table_lookup(wispr_portal_list,
+	wispr_portal = g_hash_table_lookup(wispr_portal_hash,
 					GINT_TO_POINTER(index));
 	if (!wispr_portal)
 		return;
@@ -974,21 +974,21 @@ int __connman_wispr_start(struct connman_service *service,
 
 	DBG("service %p", service);
 
-	if (!wispr_portal_list)
+	if (!wispr_portal_hash)
 		return -EINVAL;
 
 	index = __connman_service_get_index(service);
 	if (index < 0)
 		return -EINVAL;
 
-	wispr_portal = g_hash_table_lookup(wispr_portal_list,
+	wispr_portal = g_hash_table_lookup(wispr_portal_hash,
 					GINT_TO_POINTER(index));
 	if (!wispr_portal) {
 		wispr_portal = g_try_new0(struct connman_wispr_portal, 1);
 		if (!wispr_portal)
 			return -ENOMEM;
 
-		g_hash_table_replace(wispr_portal_list,
+		g_hash_table_replace(wispr_portal_hash,
 					GINT_TO_POINTER(index), wispr_portal);
 	}
 
@@ -1026,14 +1026,14 @@ void __connman_wispr_stop(struct connman_service *service)
 
 	DBG("service %p", service);
 
-	if (!wispr_portal_list)
+	if (!wispr_portal_hash)
 		return;
 
 	index = __connman_service_get_index(service);
 	if (index < 0)
 		return;
 
-	wispr_portal = g_hash_table_lookup(wispr_portal_list,
+	wispr_portal = g_hash_table_lookup(wispr_portal_hash,
 					GINT_TO_POINTER(index));
 	if (!wispr_portal)
 		return;
@@ -1042,14 +1042,14 @@ void __connman_wispr_stop(struct connman_service *service)
 	     service == wispr_portal->ipv4_context->service) ||
 	    (wispr_portal->ipv6_context &&
 	     service == wispr_portal->ipv6_context->service))
-		g_hash_table_remove(wispr_portal_list, GINT_TO_POINTER(index));
+		g_hash_table_remove(wispr_portal_hash, GINT_TO_POINTER(index));
 }
 
 int __connman_wispr_init(void)
 {
 	DBG("");
 
-	wispr_portal_list = g_hash_table_new_full(g_direct_hash,
+	wispr_portal_hash = g_hash_table_new_full(g_direct_hash,
 						g_direct_equal, NULL,
 						free_connman_wispr_portal);
 
@@ -1068,6 +1068,6 @@ void __connman_wispr_cleanup(void)
 {
 	DBG("");
 
-	g_hash_table_destroy(wispr_portal_list);
-	wispr_portal_list = NULL;
+	g_hash_table_destroy(wispr_portal_hash);
+	wispr_portal_hash = NULL;
 }
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/6] wispr: Ignore NULL proxy
  2022-08-01  8:00 [PATCH 1/6] wispr: Rename wispr_portal_list to wispr_portal_hash Daniel Wagner
@ 2022-08-01  8:00 ` Daniel Wagner
  2022-08-01  8:00 ` [PATCH 3/6] wispr: Add reference counter to portal context Daniel Wagner
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Daniel Wagner @ 2022-08-01  8:00 UTC (permalink / raw)
  To: connman; +Cc: Daniel Wagner

connmand[16822]: Failed to find URL:http://ipv6.connman.net/online/status.html
connmand[16822]: src/wispr.c:proxy_callback() proxy (null)
(connmand:16449): GLib-CRITICAL **: 10:15:43.812: g_str_has_prefix: assertion 'str != NULL' failed
---
 src/wispr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/wispr.c b/src/wispr.c
index 9bd2a2ef1d5f..a07896cabe48 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -835,7 +835,7 @@ static void proxy_callback(const char *proxy, void *user_data)
 
 	DBG("proxy %s", proxy);
 
-	if (!wp_context)
+	if (!wp_context || !proxy)
 		return;
 
 	wp_context->token = 0;
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/6] wispr: Add reference counter to portal context
  2022-08-01  8:00 [PATCH 1/6] wispr: Rename wispr_portal_list to wispr_portal_hash Daniel Wagner
  2022-08-01  8:00 ` [PATCH 2/6] wispr: Ignore NULL proxy Daniel Wagner
@ 2022-08-01  8:00 ` Daniel Wagner
  2022-08-01  8:00 ` [PATCH 4/6] wispr: Update portal context references Daniel Wagner
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Daniel Wagner @ 2022-08-01  8:00 UTC (permalink / raw)
  To: connman; +Cc: Daniel Wagner

Track the connman_wispr_portal_context live time via a
refcounter. This only adds the infrastructure to do proper reference
counting.

Fixes: CVE-2022-32293
---
 src/wispr.c | 52 ++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 42 insertions(+), 10 deletions(-)

diff --git a/src/wispr.c b/src/wispr.c
index a07896cabe48..bde7e63ba4b2 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -56,6 +56,7 @@ struct wispr_route {
 };
 
 struct connman_wispr_portal_context {
+	int refcount;
 	struct connman_service *service;
 	enum connman_ipconfig_type type;
 	struct connman_wispr_portal *wispr_portal;
@@ -97,6 +98,11 @@ static char *online_check_ipv4_url = NULL;
 static char *online_check_ipv6_url = NULL;
 static bool enable_online_to_ready_transition = false;
 
+#define wispr_portal_context_ref(wp_context) \
+	wispr_portal_context_ref_debug(wp_context, __FILE__, __LINE__, __func__)
+#define wispr_portal_context_unref(wp_context) \
+	wispr_portal_context_unref_debug(wp_context, __FILE__, __LINE__, __func__)
+
 static void connman_wispr_message_init(struct connman_wispr_message *msg)
 {
 	DBG("");
@@ -162,9 +168,6 @@ static void free_connman_wispr_portal_context(
 {
 	DBG("context %p", wp_context);
 
-	if (!wp_context)
-		return;
-
 	if (wp_context->wispr_portal) {
 		if (wp_context->wispr_portal->ipv4_context == wp_context)
 			wp_context->wispr_portal->ipv4_context = NULL;
@@ -201,9 +204,38 @@ static void free_connman_wispr_portal_context(
 	g_free(wp_context);
 }
 
+static struct connman_wispr_portal_context *
+wispr_portal_context_ref_debug(struct connman_wispr_portal_context *wp_context,
+			const char *file, int line, const char *caller)
+{
+	DBG("%p ref %d by %s:%d:%s()", wp_context,
+		wp_context->refcount + 1, file, line, caller);
+
+	__sync_fetch_and_add(&wp_context->refcount, 1);
+
+	return wp_context;
+}
+
+static void wispr_portal_context_unref_debug(
+		struct connman_wispr_portal_context *wp_context,
+		const char *file, int line, const char *caller)
+{
+	if (!wp_context)
+		return;
+
+	DBG("%p ref %d by %s:%d:%s()", wp_context,
+		wp_context->refcount - 1, file, line, caller);
+
+	if (__sync_fetch_and_sub(&wp_context->refcount, 1) != 1)
+		return;
+
+	free_connman_wispr_portal_context(wp_context);
+}
+
 static struct connman_wispr_portal_context *create_wispr_portal_context(void)
 {
-	return g_try_new0(struct connman_wispr_portal_context, 1);
+	return wispr_portal_context_ref(
+		g_new0(struct connman_wispr_portal_context, 1));
 }
 
 static void free_connman_wispr_portal(gpointer data)
@@ -215,8 +247,8 @@ static void free_connman_wispr_portal(gpointer data)
 	if (!wispr_portal)
 		return;
 
-	free_connman_wispr_portal_context(wispr_portal->ipv4_context);
-	free_connman_wispr_portal_context(wispr_portal->ipv6_context);
+	wispr_portal_context_unref(wispr_portal->ipv4_context);
+	wispr_portal_context_unref(wispr_portal->ipv6_context);
 
 	g_free(wispr_portal);
 }
@@ -452,7 +484,7 @@ static void portal_manage_status(GWebResult *result,
 		connman_info("Client-Timezone: %s", str);
 
 	if (!enable_online_to_ready_transition)
-		free_connman_wispr_portal_context(wp_context);
+		wispr_portal_context_unref(wp_context);
 
 	__connman_service_ipconfig_indicate_state(service,
 					CONNMAN_SERVICE_STATE_ONLINE, type);
@@ -616,7 +648,7 @@ static void wispr_portal_request_wispr_login(struct connman_service *service,
 				return;
 		}
 
-		free_connman_wispr_portal_context(wp_context);
+		wispr_portal_context_unref(wp_context);
 		return;
 	}
 
@@ -952,7 +984,7 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
 
 		if (wp_context->token == 0) {
 			err = -EINVAL;
-			free_connman_wispr_portal_context(wp_context);
+			wispr_portal_context_unref(wp_context);
 		}
 	} else if (wp_context->timeout == 0) {
 		wp_context->timeout = g_idle_add(no_proxy_callback, wp_context);
@@ -1001,7 +1033,7 @@ int __connman_wispr_start(struct connman_service *service,
 
 	/* If there is already an existing context, we wipe it */
 	if (wp_context)
-		free_connman_wispr_portal_context(wp_context);
+		wispr_portal_context_unref(wp_context);
 
 	wp_context = create_wispr_portal_context();
 	if (!wp_context)
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/6] wispr: Update portal context references
  2022-08-01  8:00 [PATCH 1/6] wispr: Rename wispr_portal_list to wispr_portal_hash Daniel Wagner
  2022-08-01  8:00 ` [PATCH 2/6] wispr: Ignore NULL proxy Daniel Wagner
  2022-08-01  8:00 ` [PATCH 3/6] wispr: Add reference counter to portal context Daniel Wagner
@ 2022-08-01  8:00 ` Daniel Wagner
  2022-08-01  8:00 ` [PATCH 5/6] gweb: Fix OOB write in received_data() Daniel Wagner
  2022-08-01  8:00 ` [PATCH 6/6] AUTHORS: Mention Nathan's contributions Daniel Wagner
  4 siblings, 0 replies; 6+ messages in thread
From: Daniel Wagner @ 2022-08-01  8:00 UTC (permalink / raw)
  To: connman; +Cc: Daniel Wagner

Maintain proper portal context references to avoid UAF.

Fixes: CVE-2022-32293
---
 src/wispr.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/wispr.c b/src/wispr.c
index bde7e63ba4b2..84bed33f217d 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -105,8 +105,6 @@ static bool enable_online_to_ready_transition = false;
 
 static void connman_wispr_message_init(struct connman_wispr_message *msg)
 {
-	DBG("");
-
 	msg->has_error = false;
 	msg->current_element = NULL;
 
@@ -166,8 +164,6 @@ static void free_wispr_routes(struct connman_wispr_portal_context *wp_context)
 static void free_connman_wispr_portal_context(
 		struct connman_wispr_portal_context *wp_context)
 {
-	DBG("context %p", wp_context);
-
 	if (wp_context->wispr_portal) {
 		if (wp_context->wispr_portal->ipv4_context == wp_context)
 			wp_context->wispr_portal->ipv4_context = NULL;
@@ -483,9 +479,6 @@ static void portal_manage_status(GWebResult *result,
 				&str))
 		connman_info("Client-Timezone: %s", str);
 
-	if (!enable_online_to_ready_transition)
-		wispr_portal_context_unref(wp_context);
-
 	__connman_service_ipconfig_indicate_state(service,
 					CONNMAN_SERVICE_STATE_ONLINE, type);
 
@@ -546,14 +539,17 @@ static void wispr_portal_request_portal(
 {
 	DBG("");
 
+	wispr_portal_context_ref(wp_context);
 	wp_context->request_id = g_web_request_get(wp_context->web,
 					wp_context->status_url,
 					wispr_portal_web_result,
 					wispr_route_request,
 					wp_context);
 
-	if (wp_context->request_id == 0)
+	if (wp_context->request_id == 0) {
 		wispr_portal_error(wp_context);
+		wispr_portal_context_unref(wp_context);
+	}
 }
 
 static bool wispr_input(const guint8 **data, gsize *length,
@@ -618,13 +614,15 @@ static void wispr_portal_browser_reply_cb(struct connman_service *service,
 		return;
 
 	if (!authentication_done) {
-		wispr_portal_error(wp_context);
 		free_wispr_routes(wp_context);
+		wispr_portal_error(wp_context);
+		wispr_portal_context_unref(wp_context);
 		return;
 	}
 
 	/* Restarting the test */
 	__connman_service_wispr_start(service, wp_context->type);
+	wispr_portal_context_unref(wp_context);
 }
 
 static void wispr_portal_request_wispr_login(struct connman_service *service,
@@ -700,11 +698,13 @@ static bool wispr_manage_message(GWebResult *result,
 
 		wp_context->wispr_result = CONNMAN_WISPR_RESULT_LOGIN;
 
+		wispr_portal_context_ref(wp_context);
 		if (__connman_agent_request_login_input(wp_context->service,
 					wispr_portal_request_wispr_login,
-					wp_context) != -EINPROGRESS)
+					wp_context) != -EINPROGRESS) {
 			wispr_portal_error(wp_context);
-		else
+			wispr_portal_context_unref(wp_context);
+		} else
 			return true;
 
 		break;
@@ -753,6 +753,7 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 		if (length > 0) {
 			g_web_parser_feed_data(wp_context->wispr_parser,
 								chunk, length);
+			wispr_portal_context_unref(wp_context);
 			return true;
 		}
 
@@ -770,6 +771,7 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 
 	switch (status) {
 	case 000:
+		wispr_portal_context_ref(wp_context);
 		__connman_agent_request_browser(wp_context->service,
 				wispr_portal_browser_reply_cb,
 				wp_context->status_url, wp_context);
@@ -781,11 +783,14 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 		if (g_web_result_get_header(result, "X-ConnMan-Status",
 						&str)) {
 			portal_manage_status(result, wp_context);
+			wispr_portal_context_unref(wp_context);
 			return false;
-		} else
+		} else {
+			wispr_portal_context_ref(wp_context);
 			__connman_agent_request_browser(wp_context->service,
 					wispr_portal_browser_reply_cb,
 					wp_context->redirect_url, wp_context);
+		}
 
 		break;
 	case 300:
@@ -798,6 +803,7 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 			!g_web_result_get_header(result, "Location",
 							&redirect)) {
 
+			wispr_portal_context_ref(wp_context);
 			__connman_agent_request_browser(wp_context->service,
 					wispr_portal_browser_reply_cb,
 					wp_context->status_url, wp_context);
@@ -808,6 +814,7 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 
 		wp_context->redirect_url = g_strdup(redirect);
 
+		wispr_portal_context_ref(wp_context);
 		wp_context->request_id = g_web_request_get(wp_context->web,
 				redirect, wispr_portal_web_result,
 				wispr_route_request, wp_context);
@@ -820,6 +827,7 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 
 		break;
 	case 505:
+		wispr_portal_context_ref(wp_context);
 		__connman_agent_request_browser(wp_context->service,
 				wispr_portal_browser_reply_cb,
 				wp_context->status_url, wp_context);
@@ -832,6 +840,7 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
 	wp_context->request_id = 0;
 done:
 	wp_context->wispr_msg.message_type = -1;
+	wispr_portal_context_unref(wp_context);
 	return false;
 }
 
@@ -890,6 +899,7 @@ static void proxy_callback(const char *proxy, void *user_data)
 					xml_wispr_parser_callback, wp_context);
 
 	wispr_portal_request_portal(wp_context);
+	wispr_portal_context_unref(wp_context);
 }
 
 static gboolean no_proxy_callback(gpointer user_data)
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/6] gweb: Fix OOB write in received_data()
  2022-08-01  8:00 [PATCH 1/6] wispr: Rename wispr_portal_list to wispr_portal_hash Daniel Wagner
                   ` (2 preceding siblings ...)
  2022-08-01  8:00 ` [PATCH 4/6] wispr: Update portal context references Daniel Wagner
@ 2022-08-01  8:00 ` Daniel Wagner
  2022-08-01  8:00 ` [PATCH 6/6] AUTHORS: Mention Nathan's contributions Daniel Wagner
  4 siblings, 0 replies; 6+ messages in thread
From: Daniel Wagner @ 2022-08-01  8:00 UTC (permalink / raw)
  To: connman; +Cc: Nathan Crandall

From: Nathan Crandall <ncrandall@tesla.com>

There is a mismatch of handling binary vs. C-string data with memchr
and strlen, resulting in pos, count, and bytes_read to become out of
sync and result in a heap overflow.  Instead, do not treat the buffer
as an ASCII C-string. We calculate the count based on the return value
of memchr, instead of strlen.

Fixes: CVE-2022-32292
---
 gweb/gweb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gweb/gweb.c b/gweb/gweb.c
index 12fcb1d8ab32..13c6c5f25102 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -918,7 +918,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
 		}
 
 		*pos = '\0';
-		count = strlen((char *) ptr);
+		count = pos - ptr;
 		if (count > 0 && ptr[count - 1] == '\r') {
 			ptr[--count] = '\0';
 			bytes_read--;
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 6/6] AUTHORS: Mention Nathan's contributions
  2022-08-01  8:00 [PATCH 1/6] wispr: Rename wispr_portal_list to wispr_portal_hash Daniel Wagner
                   ` (3 preceding siblings ...)
  2022-08-01  8:00 ` [PATCH 5/6] gweb: Fix OOB write in received_data() Daniel Wagner
@ 2022-08-01  8:00 ` Daniel Wagner
  4 siblings, 0 replies; 6+ messages in thread
From: Daniel Wagner @ 2022-08-01  8:00 UTC (permalink / raw)
  To: connman; +Cc: Daniel Wagner

---
 AUTHORS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/AUTHORS b/AUTHORS
index b4c6e6e7a039..59b1ddd17afa 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -178,3 +178,4 @@ Christian Taedcke <christian.taedcke@lemonbeat.com>
 Matthias Gerstner <mgerstner@suse.de>
 Sebastian Pipping <sebastian@pipping.org>
 Daniel Linjama <daniel@dev.linjama.com>
+Nathan Crandall <ncrandall@tesla.com>
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-08-01  8:07 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-01  8:00 [PATCH 1/6] wispr: Rename wispr_portal_list to wispr_portal_hash Daniel Wagner
2022-08-01  8:00 ` [PATCH 2/6] wispr: Ignore NULL proxy Daniel Wagner
2022-08-01  8:00 ` [PATCH 3/6] wispr: Add reference counter to portal context Daniel Wagner
2022-08-01  8:00 ` [PATCH 4/6] wispr: Update portal context references Daniel Wagner
2022-08-01  8:00 ` [PATCH 5/6] gweb: Fix OOB write in received_data() Daniel Wagner
2022-08-01  8:00 ` [PATCH 6/6] AUTHORS: Mention Nathan's contributions Daniel Wagner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.