From 633d2eb0f57ef17f27b6f417e4934ba0ead7e285 Mon Sep 17 00:00:00 2001
From: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
Date: Fri, 7 Mar 2025 12:06:50 +0530
Subject: [PATCH] mosquitto: backport patch for CVE-2024-8376

---
 net/mosquitto/Config.in                       |   8 +
 net/mosquitto/Makefile                        |   6 +
 ...emove-superfluous-function-arguments.patch | 208 ++++++++++++++++++
 ...eparate-trees-for-shared-normal-subs.patch | 173 +++++++++++++++
 4 files changed, 395 insertions(+)
 create mode 100644 net/mosquitto/patches/0002-Remove-superfluous-function-arguments.patch
 create mode 100644 net/mosquitto/patches/0003-Use-separate-trees-for-shared-normal-subs.patch

diff --git a/net/mosquitto/Config.in b/net/mosquitto/Config.in
index 10c7a6bc34..9e10387a17 100644
--- a/net/mosquitto/Config.in
+++ b/net/mosquitto/Config.in
@@ -27,3 +27,11 @@ config MOSQUITTO_PASSWD
     default y
     help
         mosquitto_passwd is a tool for managing password files for mosquitto.
+
+config MOSQUITTO_BRIDGE_SUPPORT
+    bool "Include mosquitto bridge support"
+    depends on PACKAGE_mosquitto-ssl
+    default y
+    help
+        Option to include moquitto broker bridge support
+
diff --git a/net/mosquitto/Makefile b/net/mosquitto/Makefile
index 56568f42bb..d06b51c40f 100644
--- a/net/mosquitto/Makefile
+++ b/net/mosquitto/Makefile
@@ -233,6 +233,12 @@ define Package/libmosquittopp/install
 	$(LN) libmosquittopp.so.1 $(1)/usr/lib/libmosquittopp.so
 endef
 
+ifeq ($(CONFIG_MOSQUITTO_BRIDGE_SUPPORT),y)
+MAKE_FLAGS += WITH_BRIDGE=yes
+else
+MAKE_FLAGS += WITH_BRIDGE=no
+endif
+
 # Applies to all...
 MAKE_FLAGS += WITH_DOCS=no UNAME=Linux
 ifeq ($(BUILD_VARIANT),nossl)
diff --git a/net/mosquitto/patches/0002-Remove-superfluous-function-arguments.patch b/net/mosquitto/patches/0002-Remove-superfluous-function-arguments.patch
new file mode 100644
index 0000000000..0317b78d6f
--- /dev/null
+++ b/net/mosquitto/patches/0002-Remove-superfluous-function-arguments.patch
@@ -0,0 +1,208 @@
+From 3bb6c9ad51f712864dea63529e0b55661c2a9e84 Mon Sep 17 00:00:00 2001
+From: "Roger A. Light" <roger@atchoo.org>
+Date: Sat, 8 Jun 2024 08:50:35 +0100
+Subject: [PATCH] Remove superfluous function arguments.
+
+---
+ apps/db_dump/stubs.c            |  3 +--
+ src/bridge.c                    |  3 +--
+ src/handle_subscribe.c          |  2 +-
+ src/handle_unsubscribe.c        |  2 +-
+ src/mosquitto_broker_internal.h |  4 ++--
+ src/persist_read.c              |  2 +-
+ src/plugin_public.c             |  2 +-
+ src/subs.c                      | 13 +++++--------
+ test/unit/persist_read_stubs.c  |  3 +--
+ test/unit/subs_test.c           |  2 +-
+ 10 files changed, 15 insertions(+), 21 deletions(-)
+
+Index: mosquitto-2.0.18/apps/db_dump/stubs.c
+===================================================================
+--- mosquitto-2.0.18.orig/apps/db_dump/stubs.c
++++ mosquitto-2.0.18/apps/db_dump/stubs.c
+@@ -101,14 +101,13 @@ int retain__store(const char *topic, str
+ 	return 0;
+ }
+ 
+-int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options, struct mosquitto__subhier **root)
++int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options)
+ {
+ 	UNUSED(context);
+ 	UNUSED(sub);
+ 	UNUSED(qos);
+ 	UNUSED(identifier);
+ 	UNUSED(options);
+-	UNUSED(root);
+ 	return 0;
+ }
+ 
+Index: mosquitto-2.0.18/src/bridge.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/bridge.c
++++ mosquitto-2.0.18/src/bridge.c
+@@ -383,8 +383,7 @@ int bridge__connect(struct mosquitto *co
+ 						context->bridge->topics[i].local_topic,
+ 						qos,
+ 						0,
+-						MQTT_SUB_OPT_NO_LOCAL | MQTT_SUB_OPT_RETAIN_AS_PUBLISHED,
+-						&db.subs) > 0){
++						MQTT_SUB_OPT_NO_LOCAL | MQTT_SUB_OPT_RETAIN_AS_PUBLISHED) > 0){
+ 
+ 				return 1;
+ 			}
+Index: mosquitto-2.0.18/src/handle_subscribe.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/handle_subscribe.c
++++ mosquitto-2.0.18/src/handle_subscribe.c
+@@ -188,7 +188,7 @@ int handle__subscribe(struct mosquitto *
+ 			}
+ 
+ 			if(allowed){
+-				rc2 = sub__add(context, sub, qos, subscription_identifier, subscription_options, &db.subs);
++				rc2 = sub__add(context, sub, qos, subscription_identifier, subscription_options);
+ 				if(rc2 > 0){
+ 					mosquitto__free(sub);
+ 					return rc2;
+Index: mosquitto-2.0.18/src/handle_unsubscribe.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/handle_unsubscribe.c
++++ mosquitto-2.0.18/src/handle_unsubscribe.c
+@@ -129,7 +129,7 @@ int handle__unsubscribe(struct mosquitto
+ 
+ 		log__printf(NULL, MOSQ_LOG_DEBUG, "\t%s", sub);
+ 		if(allowed){
+-			rc = sub__remove(context, sub, db.subs, &reason);
++			rc = sub__remove(context, sub, &reason);
+ 		}else{
+ 			rc = MOSQ_ERR_SUCCESS;
+ 		}
+Index: mosquitto-2.0.18/src/mosquitto_broker_internal.h
+===================================================================
+--- mosquitto-2.0.18.orig/src/mosquitto_broker_internal.h
++++ mosquitto-2.0.18/src/mosquitto_broker_internal.h
+@@ -675,9 +675,9 @@ void db__expire_all_messages(struct mosq
+ /* ============================================================
+  * Subscription functions
+  * ============================================================ */
+-int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options, struct mosquitto__subhier **root);
++int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options);
+ struct mosquitto__subhier *sub__add_hier_entry(struct mosquitto__subhier *parent, struct mosquitto__subhier **sibling, const char *topic, uint16_t len);
+-int sub__remove(struct mosquitto *context, const char *sub, struct mosquitto__subhier *root, uint8_t *reason);
++int sub__remove(struct mosquitto *context, const char *sub, uint8_t *reason);
+ void sub__tree_print(struct mosquitto__subhier *root, int level);
+ int sub__clean_session(struct mosquitto *context);
+ int sub__messages_queue(const char *source_id, const char *topic, uint8_t qos, int retain, struct mosquitto_msg_store **stored);
+Index: mosquitto-2.0.18/src/persist_read.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/persist_read.c
++++ mosquitto-2.0.18/src/persist_read.c
+@@ -552,7 +552,7 @@ static int persist__restore_sub(const ch
+ 
+ 	context = persist__find_or_add_context(client_id, 0);
+ 	if(!context) return 1;
+-	return sub__add(context, sub, qos, identifier, options, &db.subs);
++	return sub__add(context, sub, qos, identifier, options);
+ }
+ 
+ #endif
+Index: mosquitto-2.0.18/src/plugin_public.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/plugin_public.c
++++ mosquitto-2.0.18/src/plugin_public.c
+@@ -288,7 +288,7 @@ static void check_subscription_acls(stru
+ 				MOSQ_ACL_SUBSCRIBE);
+ 
+ 		if(rc != MOSQ_ERR_SUCCESS){
+-			sub__remove(context, context->subs[i]->topic_filter, db.subs, &reason);
++			sub__remove(context, context->subs[i]->topic_filter, &reason);
+ 		}
+ 	}
+ }
+Index: mosquitto-2.0.18/src/subs.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/subs.c
++++ mosquitto-2.0.18/src/subs.c
+@@ -575,7 +575,7 @@ struct mosquitto__subhier *sub__add_hier
+ }
+ 
+ 
+-int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options, struct mosquitto__subhier **root)
++int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options)
+ {
+ 	int rc = 0;
+ 	struct mosquitto__subhier *subhier;
+@@ -584,8 +584,6 @@ int sub__add(struct mosquitto *context,
+ 	char **topics;
+ 	size_t topiclen;
+ 
+-	assert(root);
+-	assert(*root);
+ 	assert(sub);
+ 
+ 	rc = sub__topic_tokenise(sub, &local_sub, &topics, &sharename);
+@@ -597,9 +595,9 @@ int sub__add(struct mosquitto *context,
+ 		mosquitto__free(topics);
+ 		return MOSQ_ERR_INVAL;
+ 	}
+-	HASH_FIND(hh, *root, topics[0], topiclen, subhier);
++	HASH_FIND(hh, db.subs, topics[0], topiclen, subhier);
+ 	if(!subhier){
+-		subhier = sub__add_hier_entry(NULL, root, topics[0], (uint16_t)topiclen);
++		subhier = sub__add_hier_entry(NULL, &db.subs, topics[0], (uint16_t)topiclen);
+ 		if(!subhier){
+ 			mosquitto__free(local_sub);
+ 			mosquitto__free(topics);
+@@ -616,7 +614,7 @@ int sub__add(struct mosquitto *context,
+ 	return rc;
+ }
+ 
+-int sub__remove(struct mosquitto *context, const char *sub, struct mosquitto__subhier *root, uint8_t *reason)
++int sub__remove(struct mosquitto *context, const char *sub, uint8_t *reason)
+ {
+ 	int rc = 0;
+ 	struct mosquitto__subhier *subhier;
+@@ -624,13 +622,12 @@ int sub__remove(struct mosquitto *contex
+ 	char *local_sub = NULL;
+ 	char **topics = NULL;
+ 
+-	assert(root);
+ 	assert(sub);
+ 
+ 	rc = sub__topic_tokenise(sub, &local_sub, &topics, &sharename);
+ 	if(rc) return rc;
+ 
+-	HASH_FIND(hh, root, topics[0], strlen(topics[0]), subhier);
++	HASH_FIND(hh, db.subs, topics[0], strlen(topics[0]), subhier);
+ 	if(subhier){
+ 		*reason = MQTT_RC_NO_SUBSCRIPTION_EXISTED;
+ 		rc = sub__remove_recurse(context, subhier, topics, reason, sharename);
+Index: mosquitto-2.0.18/test/unit/persist_read_stubs.c
+===================================================================
+--- mosquitto-2.0.18.orig/test/unit/persist_read_stubs.c
++++ mosquitto-2.0.18/test/unit/persist_read_stubs.c
+@@ -149,11 +149,10 @@ int acl__find_acls(struct mosquitto *con
+ }
+ 
+ 
+-int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options, struct mosquitto__subhier **root)
++int sub__add(struct mosquitto *context, const char *sub, uint8_t qos, uint32_t identifier, int options)
+ {
+ 	UNUSED(context);
+ 	UNUSED(options);
+-	UNUSED(root);
+ 
+ 	last_sub = strdup(sub);
+ 	last_qos = qos;
+Index: mosquitto-2.0.18/test/unit/subs_test.c
+===================================================================
+--- mosquitto-2.0.18.orig/test/unit/subs_test.c
++++ mosquitto-2.0.18/test/unit/subs_test.c
+@@ -58,7 +58,7 @@ static void TEST_sub_add_single(void)
+ 
+ 	db__open(&config);
+ 
+-	rc = sub__add(&context, "a/b/c/d/e", 0, 0, 0, &db.subs);
++	rc = sub__add(&context, "a/b/c/d/e", 0, 0, 0);
+ 	CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
+ 	CU_ASSERT_PTR_NOT_NULL(db.subs);
+ 	if(db.subs){
diff --git a/net/mosquitto/patches/0003-Use-separate-trees-for-shared-normal-subs.patch b/net/mosquitto/patches/0003-Use-separate-trees-for-shared-normal-subs.patch
new file mode 100644
index 0000000000..88b63b72de
--- /dev/null
+++ b/net/mosquitto/patches/0003-Use-separate-trees-for-shared-normal-subs.patch
@@ -0,0 +1,173 @@
+From 1914b3ee2a18102d0a94cbdbbfeae1afa03edd17 Mon Sep 17 00:00:00 2001
+From: "Roger A. Light" <roger@atchoo.org>
+Date: Sat, 8 Jun 2024 09:41:08 +0100
+Subject: [PATCH] Use separate trees for shared/normal subs
+
+Fixes Eclipse #217, #218.
+---
+ ChangeLog.txt                    |  4 +++
+ src/database.c                   | 13 +++++++---
+ src/loop.c                       |  3 ++-
+ src/mosquitto_broker_internal.h  |  3 ++-
+ src/persist_write.c              |  8 +++++-
+ src/subs.c                       | 42 ++++++++++++++++++++++++--------
+ test/broker/data/REGRESSION.json | 31 +++++++++++++++++++++++
+ test/broker/msg_sequence_test.py |  4 +++
+ test/unit/subs_test.c            |  7 +++---
+ 9 files changed, 95 insertions(+), 20 deletions(-)
+
+Index: mosquitto-2.0.18/src/database.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/database.c
++++ mosquitto-2.0.18/src/database.c
+@@ -199,12 +199,16 @@ int db__open(struct mosquitto__config *c
+ 	/* Initialize the hashtable */
+ 	db.clientid_index_hash = NULL;
+ 
+-	db.subs = NULL;
++	db.normal_subs = NULL;
++	db.shared_subs = NULL;
+ 
+-	subhier = sub__add_hier_entry(NULL, &db.subs, "", 0);
++	subhier = sub__add_hier_entry(NULL, &db.shared_subs, "", 0);
+ 	if(!subhier) return MOSQ_ERR_NOMEM;
+ 
+-	subhier = sub__add_hier_entry(NULL, &db.subs, "$SYS", (uint16_t)strlen("$SYS"));
++	subhier = sub__add_hier_entry(NULL, &db.normal_subs, "", 0);
++	if(!subhier) return MOSQ_ERR_NOMEM;
++
++	subhier = sub__add_hier_entry(NULL, &db.normal_subs, "$SYS", (uint16_t)strlen("$SYS"));
+ 	if(!subhier) return MOSQ_ERR_NOMEM;
+ 
+ 	retain__init();
+@@ -240,7 +244,8 @@ static void subhier_clean(struct mosquit
+ 
+ int db__close(void)
+ {
+-	subhier_clean(&db.subs);
++	subhier_clean(&db.normal_subs);
++	subhier_clean(&db.shared_subs);
+ 	retain__clean(&db.retains);
+ 	db__msg_store_clean();
+ 
+Index: mosquitto-2.0.18/src/loop.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/loop.c
++++ mosquitto-2.0.18/src/loop.c
+@@ -241,7 +241,8 @@ int mosquitto_main_loop(struct mosquitto
+ 			flag_reload = false;
+ 		}
+ 		if(flag_tree_print){
+-			sub__tree_print(db.subs, 0);
++			sub__tree_print(db.normal_subs, 0);
++			sub__tree_print(db.shared_subs, 0);
+ 			flag_tree_print = false;
+ #ifdef WITH_XTREPORT
+ 			xtreport();
+Index: mosquitto-2.0.18/src/mosquitto_broker_internal.h
+===================================================================
+--- mosquitto-2.0.18.orig/src/mosquitto_broker_internal.h
++++ mosquitto-2.0.18/src/mosquitto_broker_internal.h
+@@ -442,7 +442,8 @@ struct mosquitto_message_v5{
+ 
+ struct mosquitto_db{
+ 	dbid_t last_db_id;
+-	struct mosquitto__subhier *subs;
++	struct mosquitto__subhier *normal_subs;
++	struct mosquitto__subhier *shared_subs;
+ 	struct mosquitto__retainhier *retains;
+ 	struct mosquitto *contexts_by_id;
+ 	struct mosquitto *contexts_by_sock;
+Index: mosquitto-2.0.18/src/persist_write.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/persist_write.c
++++ mosquitto-2.0.18/src/persist_write.c
+@@ -266,7 +266,13 @@ static int persist__subs_save_all(FILE *
+ {
+ 	struct mosquitto__subhier *subhier, *subhier_tmp;
+ 
+-	HASH_ITER(hh, db.subs, subhier, subhier_tmp){
++	HASH_ITER(hh, db.normal_subs, subhier, subhier_tmp){
++		if(subhier->children){
++			persist__subs_save(db_fptr, subhier->children, "", 0);
++		}
++	}
++
++	HASH_ITER(hh, db.shared_subs, subhier, subhier_tmp){
+ 		if(subhier->children){
+ 			persist__subs_save(db_fptr, subhier->children, "", 0);
+ 		}
+Index: mosquitto-2.0.18/src/subs.c
+===================================================================
+--- mosquitto-2.0.18.orig/src/subs.c
++++ mosquitto-2.0.18/src/subs.c
+@@ -595,16 +595,29 @@ int sub__add(struct mosquitto *context,
+ 		mosquitto__free(topics);
+ 		return MOSQ_ERR_INVAL;
+ 	}
+-	HASH_FIND(hh, db.subs, topics[0], topiclen, subhier);
+-	if(!subhier){
+-		subhier = sub__add_hier_entry(NULL, &db.subs, topics[0], (uint16_t)topiclen);
++
++	if(sharename){
++		HASH_FIND(hh, db.shared_subs, topics[0], topiclen, subhier);
+ 		if(!subhier){
+-			mosquitto__free(local_sub);
+-			mosquitto__free(topics);
+-			log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
+-			return MOSQ_ERR_NOMEM;
++			subhier = sub__add_hier_entry(NULL, &db.shared_subs, topics[0], (uint16_t)topiclen);
++			if(!subhier){
++				mosquitto__free(local_sub);
++				mosquitto__free(topics);
++				log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
++				return MOSQ_ERR_NOMEM;
++			}
++		}
++	}else{
++		HASH_FIND(hh, db.normal_subs, topics[0], topiclen, subhier);
++		if(!subhier){
++			subhier = sub__add_hier_entry(NULL, &db.normal_subs, topics[0], (uint16_t)topiclen);
++			if(!subhier){
++				mosquitto__free(local_sub);
++				mosquitto__free(topics);
++				log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
++				return MOSQ_ERR_NOMEM;
++			}
+ 		}
+-
+ 	}
+ 	rc = sub__add_context(context, sub, qos, identifier, options, subhier, topics, sharename);
+ 
+@@ -627,7 +640,11 @@ int sub__remove(struct mosquitto *contex
+ 	rc = sub__topic_tokenise(sub, &local_sub, &topics, &sharename);
+ 	if(rc) return rc;
+ 
+-	HASH_FIND(hh, db.subs, topics[0], strlen(topics[0]), subhier);
++	if(sharename){
++		HASH_FIND(hh, db.shared_subs, topics[0], strlen(topics[0]), subhier);
++	}else{
++		HASH_FIND(hh, db.normal_subs, topics[0], strlen(topics[0]), subhier);
++	}
+ 	if(subhier){
+ 		*reason = MQTT_RC_NO_SUBSCRIPTION_EXISTED;
+ 		rc = sub__remove_recurse(context, subhier, topics, reason, sharename);
+@@ -656,7 +673,17 @@ int sub__messages_queue(const char *sour
+ 	*/
+ 	db__msg_store_ref_inc(*stored);
+ 
+-	HASH_FIND(hh, db.subs, split_topics[0], strlen(split_topics[0]), subhier);
++	HASH_FIND(hh, db.normal_subs, split_topics[0], strlen(split_topics[0]), subhier);
++	if(subhier){
++		rc = sub__search(subhier, split_topics, source_id, topic, qos, retain, *stored);
++	}
++
++	HASH_FIND(hh, db.shared_subs, split_topics[0], strlen(split_topics[0]), subhier);
++	if(subhier){
++		rc = sub__search(subhier, split_topics, source_id, topic, qos, retain, *stored);
++	}
++
++	HASH_FIND(hh, db.shared_subs, split_topics[0], strlen(split_topics[0]), subhier);
+ 	if(subhier){
+ 		rc = sub__search(subhier, split_topics, source_id, topic, qos, retain, *stored);
+ 	}
-- 
GitLab