[PATCH 1/2] technology: Ignore invalid UTF-8 tethering identifier and passphrase

Giuseppe Eletto <[email protected]> Wed, 8 Jul 2026 19:56:49 +0200
Newsgroups dev.linux.lists.connman
Message-ID <[email protected]>
technology_load() reads the WiFi tethering identifier and passphrase from
the global settings file. The passphrase is additionally passed through
g_strcompress(), which turns stored octal escapes such as "\215\301\252"
back into raw bytes.

When the settings file is corrupted, for example after an unclean shutdown
on flash based storage, these strings may no longer be valid UTF-8:

  [WiFi]
  Tethering.Identifier=@?????
  Tethering.Passphrase=PW\215\301\252\252

Both values are later handed to D-Bus in append_properties() when the
technology is registered and the TechnologyAdded signal is emitted.
libdbus aborts the process when a string that is not valid UTF-8 is
appended to a message, so connmand crashes on every start and never
recovers on its own:

  Aborting (signal 6) [/usr/sbin/connmand]
  #6  libdbus-1.so.3  dbus_message_iter_append_basic
  #7  connmand        connman_dbus_dict_append_basic
  #8  connmand        append_properties
  #9  connmand        technology_added_signal
  #10 connmand        technology_dbus_register
  #11 connmand        technology_get

Validate both values with g_utf8_validate() right after loading them and
ignore the ones that are not valid UTF-8.
---
 src/technology.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/technology.c b/src/technology.c
index 933070f0..8bdb296e 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -481,11 +481,27 @@ static void technology_load(struct connman_technology *technology)
 	technology->tethering_ident = g_key_file_get_string(keyfile,
 				identifier, "Tethering.Identifier", NULL);
 
+	if (technology->tethering_ident &&
+			!g_utf8_validate(technology->tethering_ident, -1, NULL)) {
+		connman_warn("Ignoring invalid Tethering.Identifier for %s",
+								identifier);
+		g_free(technology->tethering_ident);
+		technology->tethering_ident = NULL;
+	}
+
 	enc = g_key_file_get_string(keyfile,
 				identifier, "Tethering.Passphrase", NULL);
 	if (enc) {
 		technology->tethering_passphrase = g_strcompress(enc);
 		g_free(enc);
+
+		if (!g_utf8_validate(technology->tethering_passphrase,
+								-1, NULL)) {
+			connman_warn("Ignoring invalid Tethering.Passphrase "
+						"for %s", identifier);
+			g_free(technology->tethering_passphrase);
+			technology->tethering_passphrase = NULL;
+		}
 	}
 
 	technology->tethering_freq = g_key_file_get_integer(keyfile,
-- 
2.50.1