From: Lennart Poettering Date: Fri, 20 Jun 2025 11:16:10 +0000 (+0200) Subject: core: escape UTF-8 in mount unit Where field before sending to clients X-Git-Tag: v256.17~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=af6273bc34a40eca5c221af96d6f997d8745b0d2;p=thirdparty%2Fsystemd.git core: escape UTF-8 in mount unit Where field before sending to clients Followup for: 4804da58536ab7ad46178a03f4d2da49fd8e4ba2 #27541 Fixes: #36206 (cherry picked from commit 222b0b05ce9ac29283cd89cf98444c4da3373568) (cherry picked from commit 72db7dfd2778ac399eedac580b658e2d75e577a4) --- diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c index f6a9ea97b77..37f5ca115a9 100644 --- a/src/core/dbus-mount.c +++ b/src/core/dbus-mount.c @@ -12,6 +12,27 @@ #include "unit.h" #include "utf8.h" +static int property_get_where( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Mount *m = ASSERT_PTR(userdata); + + assert(bus); + assert(reply); + + _cleanup_free_ char *escaped = mount_get_where_escaped(m); + if (!escaped) + return -ENOMEM; + + return sd_bus_message_append_basic(reply, 's', escaped); +} + static int property_get_what( sd_bus *bus, const char *path, @@ -61,7 +82,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResu const sd_bus_vtable bus_mount_vtable[] = { SD_BUS_VTABLE_START(0), - SD_BUS_PROPERTY("Where", "s", NULL, offsetof(Mount, where), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Where", "s", property_get_where, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("What", "s", property_get_what, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("Options", "s", property_get_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("Type", "s", property_get_type, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), diff --git a/src/core/mount.c b/src/core/mount.c index 66917dfa88b..52a3a1ad80c 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -648,7 +648,11 @@ static int mount_add_extras(Mount *m) { path_simplify(m->where); if (!u->description) { - r = unit_set_description(u, m->where); + _cleanup_free_ char *w = mount_get_where_escaped(m); + if (!w) + return log_oom(); + + r = unit_set_description(u, w); if (r < 0) return r; } @@ -2355,6 +2359,15 @@ static int mount_subsystem_ratelimited(Manager *m) { return sd_event_source_is_ratelimited(m->mount_event_source); } +char* mount_get_where_escaped(const Mount *m) { + assert(m); + + if (!m->where) + return strdup(""); + + return utf8_escape_invalid(m->where); +} + char* mount_get_what_escaped(const Mount *m) { _cleanup_free_ char *escaped = NULL; const char *s = NULL; diff --git a/src/core/mount.h b/src/core/mount.h index a029dc87aca..925a6e09fdf 100644 --- a/src/core/mount.h +++ b/src/core/mount.h @@ -98,6 +98,7 @@ void mount_fd_event(Manager *m, int events); int mount_invalidate_state_by_path(Manager *manager, const char *path); +char* mount_get_where_escaped(const Mount *m); char* mount_get_what_escaped(const Mount *m); char* mount_get_options_escaped(const Mount *m); const char* mount_get_fstype(const Mount *m); diff --git a/test/units/TEST-07-PID1.mount-invalid-chars.sh b/test/units/TEST-07-PID1.mount-invalid-chars.sh index a8793348696..cd2ca78fdfc 100755 --- a/test/units/TEST-07-PID1.mount-invalid-chars.sh +++ b/test/units/TEST-07-PID1.mount-invalid-chars.sh @@ -23,12 +23,13 @@ TMP_MOUNTINFO="$(mktemp)" cp /proc/1/mountinfo "$TMP_MOUNTINFO" # Add a mount entry with a "Unicode non-character" in it -LANG="C.UTF-8" printf '69 1 252:2 / /foo/mountinfo rw,relatime shared:1 - cifs //foo\ufffebar rw,seclabel\n' >>"$TMP_MOUNTINFO" +LANG="C.UTF-8" printf '69 1 252:2 / /foo/mount\ufffeinfo rw,relatime shared:1 - cifs //foo\ufffebar rw,seclabel\n' >>"$TMP_MOUNTINFO" mount --bind "$TMP_MOUNTINFO" /proc/1/mountinfo systemctl daemon-reload # On affected versions this would throw an error: # Failed to get properties: Bad message -systemctl status foo-mountinfo.mount +systemctl list-units -t mount +systemctl status foo-mount\\xef\\xbf\\xbeinfo.mount umount /proc/1/mountinfo systemctl daemon-reload