File usbmuxd-CVE-2025-66004.patch of Package usbmuxd.41987

From 3ded00c9985a5108cfc7591a309f9a23d57a8cba Mon Sep 17 00:00:00 2001
From: Nikias Bassen <nikias@gmx.li>
Date: Sat, 6 Dec 2025 02:13:05 +0100
Subject: [PATCH] conf: Make sure to sanitize input for SavePairRecord command

A path traversal vulnerability was discovered in usbmuxd that allows
arbitrary, unprivileged local users to delete and create files named
`*.plist` as the `usbmux` user.

See https://bugzilla.opensuse.org/show_bug.cgi?id=1254302
---
 src/conf.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff -urp usbmuxd-1.1.0.orig/src/conf.c usbmuxd-1.1.0/src/conf.c
--- usbmuxd-1.1.0.orig/src/conf.c	2014-10-06 11:55:44.000000000 -0500
+++ usbmuxd-1.1.0/src/conf.c	2025-12-12 11:52:54.848674209 -0600
@@ -34,6 +34,7 @@
 #include <libgen.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <ctype.h>
 
 #ifdef WIN32
 #include <shlobj.h>
@@ -385,6 +386,44 @@ void config_get_system_buid(char **syste
 	usbmuxd_log(LL_DEBUG, "using %s as %s", *system_buid, CONFIG_SYSTEM_BUID_KEY);
 }
 
+static int my_plist_is_binary(const char *plist_data, uint32_t length)
+{
+    if (length < 8) {
+        return 0;
+    }
+
+    return (memcmp(plist_data, "bplist00", 8) == 0);
+}
+
+#define SKIP_WS(blob, pos, len) \
+    while (pos < len && ((blob[pos] == ' ') || (blob[pos] == '\t') || (blob[pos] == '\r') || (blob[pos] == '\n'))) pos++;
+#define FIND_NEXT(blob, pos, len, chr) \
+    while (pos < len && (blob[pos] != chr)) pos++;
+
+static void my_plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist)
+{
+    if (!plist) {
+        return;
+    }
+    *plist = NULL;
+    if (!plist_data || length == 0) {
+        return;
+    }
+    if (my_plist_is_binary(plist_data, length)) {
+        plist_from_bin(plist_data, length, plist);
+    } else {
+        uint32_t pos = 0;
+        /* skip whitespace */
+        SKIP_WS(plist_data, pos, length);
+        if (pos >= length) {
+            return;
+        }
+        if (plist_data[pos] == '<' && (length-pos > 3) && !isxdigit(plist_data[pos+1]) && !isxdigit(plist_data[pos+2]) && !isxdigit(plist_data[pos+3])) {
+            plist_from_xml(plist_data, length, plist);
+        }
+    }
+}
+
 /**
  * Store a pairing record for the given device identifier.
  *
@@ -401,13 +440,19 @@ int config_set_device_record(const char
 	if (!udid || !record_data || record_size < 8)
 		return -EINVAL;
 
-	plist_t plist = NULL;
-	if (memcmp(record_data, "bplist00", 8) == 0) {
-		plist_from_bin(record_data, record_size, &plist);
-	} else {
-		plist_from_xml(record_data, record_size, &plist);
+	/* verify udid input */
+	const char* u = udid;
+	while (*u != '\0') {
+		if (!isalnum(*u) && (*u != '-')) {
+			usbmuxd_log(LL_ERROR, "ERROR: %s: udid contains invalid character.\n", __func__);
+			return -EINVAL;
+		}
+		u++;
 	}
 
+	plist_t plist = NULL;
+	my_plist_from_memory(record_data, record_size, &plist);
+
 	if (!plist || plist_get_node_type(plist) != PLIST_DICT) {
 		if (plist)
 			plist_free(plist);
Only in usbmuxd-1.1.0/src: conf.c.orig
openSUSE Build Service is sponsored by