aboutsummaryrefslogtreecommitdiff
#!@abs_top_builddir@/guile \
--no-auto-compile -e main -s
!#
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2013 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2018 Mathieu Lirzin <mthl@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

;; IMPORTANT: We must avoid loading any modules from Guix here,
;; because we need to adjust the guile load paths first.
;; It's okay to import modules from core Guile though.

(define-syntax-rule (push! elt v) (set! v (cons elt v)))

(define (augment-load-paths!)
  ;; Add installed modules to load-path.
  (push! "@guilemoduledir@" %load-path)
  (push! "@guileobjectdir@" %load-compiled-path))

(define* (main #:optional (args (command-line)))
  (unless (getenv "GUIX_UNINSTALLED")
    (augment-load-paths!))

  (let ((guix-main (module-ref (resolve-interface '(guix ui))
                               'guix-main)))
    (bindtextdomain "guix" "@localedir@")
    (bindtextdomain "guix-packages" "@localedir@")
    ;; XXX: It would be more convenient to change it to:
    ;;   (exit (apply guix-main (command-line)))
    ;; but since the 'guix' command is not updated by 'guix pull', we cannot
    ;; really do it now.
    (apply guix-main args)))

;;; Local Variables:
;;; mode: scheme
;;; End:
d='n36' href='#n36'>36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
https://git.kernel.org/pub/scm/network/connman/connman.git/patch/?id=72343929836de80727a27d6744c869dff045757c

From 72343929836de80727a27d6744c869dff045757c Mon Sep 17 00:00:00 2001
From: Daniel Wagner <wagi@monom.org>
Date: Tue, 5 Jul 2022 08:32:12 +0200
Subject: wispr: Add reference counter to portal context

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 a07896ca..bde7e63b 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)
-- 
cgit