|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
From 43ccd990b8478b5aaf9b1618e0a5c3dd8924a9ee Mon Sep 17 00:00:00 2001
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
From: Goffredo Baroncelli <kreijack@libero.it>
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
Date: Thu, 6 Feb 2014 19:09:59 +0100
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
Subject: [PATCH] core: fix crashes if locale.conf contains invalid utf-8
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
string
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
In the parse_env_file_push() and load_env_file_push() functions, there
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
are two assert() call to check if the key or value parameters are utf8 valid.
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
If the strings aren't utf8 valid, assert does abort.
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
These function are used early by systemd to parse some files. For
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
example '/etc/locale.conf'. In my case this file contained a not utf8
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
sequence, which is bad, but systemd crashed during the boot, which
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
is even worse!
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
The enclosed patch removes the assert and return -EINVAL if the
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
sequence is invalid. This is possible because the caller of these
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
function [1] checks the errors.
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
So the check of an invalid utf8 sequence is still performed, but
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
systemd doesn't crash anymore and logs the error.
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
[1] parse_env_file_internal(), invoked by load_env_file() and
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
parse_env_file()
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
---
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
src/shared/fileio.c | 77 ++++++++++++++++++++++++++++++-----------------------
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
1 file changed, 43 insertions(+), 34 deletions(-)
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
index 733b320..d28e38a 100644
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
--- a/src/shared/fileio.c
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+++ b/src/shared/fileio.c
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
@@ -462,35 +462,39 @@ fail:
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
static int parse_env_file_push(const char *filename, unsigned line,
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
const char *key, char *value, void *userdata) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- assert(utf8_is_valid(key));
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- if (value && !utf8_is_valid(value))
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ const char *k;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ va_list aq, *ap = userdata;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ if (!utf8_is_valid(key)) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.",
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ filename, line, key);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ return -EINVAL;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ }
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ if (value && !utf8_is_valid(value)) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
/* FIXME: filter UTF-8 */
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- log_error("%s:%u: invalid UTF-8 for key %s: '%s', ignoring.",
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
filename, line, key, value);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- else {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- const char *k;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- va_list* ap = (va_list*) userdata;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- va_list aq;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ return -EINVAL;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ }
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- va_copy(aq, *ap);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ va_copy(aq, *ap);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- while ((k = va_arg(aq, const char *))) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- char **v;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ while ((k = va_arg(aq, const char *))) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ char **v;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- v = va_arg(aq, char **);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ v = va_arg(aq, char **);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- if (streq(key, k)) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- va_end(aq);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- free(*v);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- *v = value;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- return 1;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- }
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ if (streq(key, k)) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ va_end(aq);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ free(*v);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ *v = value;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ return 1;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
-
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- va_end(aq);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ va_end(aq);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
free(value);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
return 0;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
@@ -514,26 +518,31 @@ int parse_env_file(
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
static int load_env_file_push(const char *filename, unsigned line,
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
const char *key, char *value, void *userdata) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- assert(utf8_is_valid(key));
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ char ***m = userdata;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ char *p;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ int r;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- if (value && !utf8_is_valid(value))
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ if (!utf8_is_valid(key)) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.",
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ filename, line, key);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ return -EINVAL;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ }
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ if (value && !utf8_is_valid(value)) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
/* FIXME: filter UTF-8 */
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- log_error("%s:%u: invalid UTF-8 for key %s: '%s', ignoring.",
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
filename, line, key, value);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- else {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- char ***m = userdata;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- char *p;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- int r;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ return -EINVAL;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ }
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- p = strjoin(key, "=", strempty(value), NULL);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- if (!p)
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- return -ENOMEM;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ p = strjoin(key, "=", strempty(value), NULL);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ if (!p)
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ return -ENOMEM;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- r = strv_push(m, p);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- if (r < 0) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- free(p);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- return r;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
- }
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ r = strv_push(m, p);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ if (r < 0) {
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ free(p);
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
+ return r;
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
|
|
Zbigniew Jędrzejewski-Szmek |
ca73a2 |
free(value);
|