diff options
author | Michal Sekletar <msekleta@redhat.com> | 2023-05-05 12:50:15 +0200 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2023-05-10 00:01:32 +0100 |
commit | aaf7b0e41105d7b7cf30912cdac32820f011a219 (patch) | |
tree | f32e1a4395d49379314e27ccdcc25ca32a47a164 /src | |
parent | 539af5c4413efbcdb57713b7ad563440217b28a5 (diff) | |
download | systemd-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')
-rw-r--r-- | src/core/mount.c | 35 |
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) |