summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorMichal Sekletar <msekleta@redhat.com>2023-05-05 12:50:15 +0200
committerLuca Boccassi <luca.boccassi@gmail.com>2023-05-10 00:01:32 +0100
commitaaf7b0e41105d7b7cf30912cdac32820f011a219 (patch)
treef32e1a4395d49379314e27ccdcc25ca32a47a164 /src/core
parent539af5c4413efbcdb57713b7ad563440217b28a5 (diff)
downloadsystemd-aaf7b0e41105d7b7cf30912cdac32820f011a219.tar.gz
core/mount: replace invalid UTF-8 code points in "what" and "options"
Previously, these strings were copied w/o any modification. However, if mount table contained e.g. remote fs mount like NFS or CIFS that was mounted from server running with non UTF-8 locale then those strings might have contained some non UTF-8 characters. If then client asked about status of such mount unit we tried to forward these non UTF-8 strings over D-Bus. That is the violation of the protocol and we ended up kicked from the bus.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/mount.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/src/core/mount.c b/src/core/mount.c
index 549d7dbf98..b87b57b7ad 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -34,6 +34,7 @@
#include "strv.h"
#include "unit-name.h"
#include "unit.h"
+#include "utf8.h"
#define RETRY_UMOUNT_MAX 32
@@ -274,13 +275,35 @@ static int update_parameters_proc_self_mountinfo(
p = &m->parameters_proc_self_mountinfo;
- r = free_and_strdup(&p->what, what);
- if (r < 0)
- return r;
+ if (what && !utf8_is_valid(what)) {
+ _cleanup_free_ char *what_escaped = NULL;
- q = free_and_strdup(&p->options, options);
- if (q < 0)
- return q;
+ what_escaped = utf8_escape_invalid(what);
+ if (!what_escaped)
+ return -ENOMEM;
+
+ r = !streq_ptr(p->what, what_escaped);
+ free_and_replace(p->what, what_escaped);
+ } else {
+ r = free_and_strdup(&p->what, what);
+ if (r < 0)
+ return r;
+ }
+
+ if (options && !utf8_is_valid(options)) {
+ _cleanup_free_ char *options_escaped = NULL;
+
+ options_escaped = utf8_escape_invalid(options);
+ if (!options_escaped)
+ return -ENOMEM;
+
+ q = !streq_ptr(p->options, options_escaped);
+ free_and_replace(p->options, options_escaped);
+ } else {
+ q = free_and_strdup(&p->options, options);
+ if (q < 0)
+ return q;
+ }
w = free_and_strdup(&p->fstype, fstype);
if (w < 0)