Skip to content

Commit

Permalink
conf: enforce UTF8 validty everywhere
Browse files Browse the repository at this point in the history
we need to make sure that configuration data we expose via the bus ends
up in using getting an assert(). Even though configuration data is only
parsed from trusted sources we should be more careful with what we read.
  • Loading branch information
poettering committed Mar 12, 2012
1 parent 669e49f commit 7f110ff
Show file tree
Hide file tree
Showing 8 changed files with 386 additions and 71 deletions.
6 changes: 4 additions & 2 deletions Makefile.am
Expand Up @@ -468,7 +468,8 @@ libsystemd_basic_la_SOURCES = \
src/socket-util.c \
src/log.c \
src/ratelimit.c \
src/exit-status.c
src/exit-status.c \
src/utf8.c

libsystemd_basic_la_CFLAGS = \
$(AM_CFLAGS) \
Expand Down Expand Up @@ -649,7 +650,8 @@ EXTRA_DIST += \
src/dbus-loop.h \
src/spawn-agent.h \
src/acl-util.h \
src/logs-show.h
src/logs-show.h \
src/utf8.h

MANPAGES = \
man/systemd.1 \
Expand Down
6 changes: 4 additions & 2 deletions TODO
Expand Up @@ -18,6 +18,10 @@ Bugfixes:

Features:

* document crypttab(5)

* There's currently no way to cancel fsck (used to be possible via C-c or c on the console)

* hook up /dev/watchdog with main event loop for embedded, server uses

* man: for some reason the HTML versions of the man pages are currently not being packaged
Expand Down Expand Up @@ -115,8 +119,6 @@ Features:

* document that %% can be used to write % in a string that is specifier extended

* check utf8 everywhere

* when an instanced service exits, remove its parent cgroup too if possible.

* Make libselinux, libattr, libcap, libdl dependencies only of the tools which actually need them.
Expand Down
66 changes: 51 additions & 15 deletions src/conf-parser.c
Expand Up @@ -30,6 +30,7 @@
#include "macro.h"
#include "strv.h"
#include "log.h"
#include "utf8.h"

int config_item_table_lookup(
void *table,
Expand Down Expand Up @@ -584,14 +585,23 @@ int config_parse_string(
assert(rvalue);
assert(data);

if (*rvalue) {
if (!(n = strdup(rvalue)))
return -ENOMEM;
} else
n = NULL;
n = cunescape(rvalue);
if (!n)
return -ENOMEM;

if (!utf8_is_valid(n)) {
log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
free(n);
return 0;
}

free(*s);
*s = n;
if (*n)
*s = n;
else {
free(n);
*s = NULL;
}

return 0;
}
Expand All @@ -614,12 +624,18 @@ int config_parse_path(
assert(rvalue);
assert(data);

if (!utf8_is_valid(rvalue)) {
log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
return 0;
}

if (!path_is_absolute(rvalue)) {
log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue);
return 0;
}

if (!(n = strdup(rvalue)))
n = strdup(rvalue);
if (!n)
return -ENOMEM;

path_kill_slashes(n);
Expand All @@ -646,6 +662,7 @@ int config_parse_strv(
unsigned k;
size_t l;
char *state;
int r;

assert(filename);
assert(lvalue);
Expand All @@ -656,7 +673,8 @@ int config_parse_strv(
FOREACH_WORD_QUOTED(w, l, rvalue, state)
k++;

if (!(n = new(char*, k+1)))
n = new(char*, k+1);
if (!n)
return -ENOMEM;

if (*sv)
Expand All @@ -665,9 +683,21 @@ int config_parse_strv(
else
k = 0;

FOREACH_WORD_QUOTED(w, l, rvalue, state)
if (!(n[k++] = cunescape_length(w, l)))
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
n[k] = cunescape_length(w, l);
if (!n[k]) {
r = -ENOMEM;
goto fail;
}

if (!utf8_is_valid(n[k])) {
log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
free(n[k]);
continue;
}

k++;
}

n[k] = NULL;
free(*sv);
Expand All @@ -680,7 +710,7 @@ int config_parse_strv(
free(n[k-1]);
free(n);

return -ENOMEM;
return r;
}

int config_parse_path_strv(
Expand Down Expand Up @@ -710,7 +740,8 @@ int config_parse_path_strv(
FOREACH_WORD_QUOTED(w, l, rvalue, state)
k++;

if (!(n = new(char*, k+1)))
n = new(char*, k+1);
if (!n)
return -ENOMEM;

k = 0;
Expand All @@ -719,19 +750,25 @@ int config_parse_path_strv(
n[k] = (*sv)[k];

FOREACH_WORD_QUOTED(w, l, rvalue, state) {
if (!(n[k] = cunescape_length(w, l))) {
n[k] = strndup(w, l);
if (!n[k]) {
r = -ENOMEM;
goto fail;
}

if (!utf8_is_valid(n[k])) {
log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
free(n[k]);
continue;
}

if (!path_is_absolute(n[k])) {
log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue);
free(n[k]);
continue;
}

path_kill_slashes(n[k]);

k++;
}

Expand All @@ -742,7 +779,6 @@ int config_parse_path_strv(
return 0;

fail:
free(n[k]);
for (; k > 0; k--)
free(n[k-1]);
free(n);
Expand Down

0 comments on commit 7f110ff

Please sign in to comment.