summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-09-24 14:55:57 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-09-25 13:36:34 +0200
commit7bb553bb98a57b4e03804f8192bdc5a534325582 (patch)
tree3040cd663b06af6e92f57ef8b1100956469a9f40 /src
parentcore/execute: escape the separator in exported paths (diff)
downloadsystemd-7bb553bb98a57b4e03804f8192bdc5a534325582.tar.xz
systemd-7bb553bb98a57b4e03804f8192bdc5a534325582.zip
fstab,crypttab: allow escaping of commas
Fixes #17035. We use "," as the separator between arguments in fstab and crypttab options field, but the kernel started using "," within arguments. Users will need to escape those nested commas.
Diffstat (limited to 'src')
-rw-r--r--src/cryptsetup/cryptsetup.c5
-rw-r--r--src/shared/fstab-util.c23
-rw-r--r--src/test/test-fstab-util.c19
3 files changed, 34 insertions, 13 deletions
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 78efe19f23..10472bde26 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -294,7 +294,7 @@ static int parse_options(const char *options) {
_cleanup_free_ char *word = NULL;
int r;
- r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS);
+ r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
if (r < 0)
return log_error_errno(r, "Failed to parse options: %m");
if (r == 0)
@@ -874,6 +874,9 @@ static int run(int argc, char *argv[]) {
return r;
}
+ log_debug("%s %s ← %s type=%s cipher=%s", __func__,
+ argv[2], argv[3], strempty(arg_type), strempty(arg_cipher));
+
/* A delicious drop of snake oil */
(void) mlockall(MCL_FUTURE);
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
index d883eca5c7..ca88813602 100644
--- a/src/shared/fstab-util.c
+++ b/src/shared/fstab-util.c
@@ -95,7 +95,19 @@ int fstab_filter_options(const char *opts, const char *names,
if (!ret_filtered) {
for (const char *word = opts;;) {
- const char *end = word + strcspn(word, ",");
+ const char *end = word;
+
+ /* Look for an *non-escaped* comma separator. Only commas can be escaped, so "\," is
+ * the only valid escape sequence, so we can do a very simple test here. */
+ for (;;) {
+ size_t n = strcspn(end, ",");
+
+ end += n;
+ if (n > 0 && end[-1] == '\\')
+ end++;
+ else
+ break;
+ }
NULSTR_FOREACH(name, names) {
if (end < word + strlen(name))
@@ -128,9 +140,10 @@ int fstab_filter_options(const char *opts, const char *names,
break;
}
} else {
- stor = strv_split(opts, ",");
- if (!stor)
- return -ENOMEM;
+ r = strv_split_full(&stor, opts, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
+ if (r < 0)
+ return r;
+
strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
if (!strv)
return -ENOMEM;
@@ -165,7 +178,7 @@ answer:
if (ret_filtered) {
char *f;
- f = strv_join(strv, ",");
+ f = strv_join_full(strv, ",", NULL, true);
if (!f)
return -ENOMEM;
diff --git a/src/test/test-fstab-util.c b/src/test/test-fstab-util.c
index 187be69d15..f3506045a1 100644
--- a/src/test/test-fstab-util.c
+++ b/src/test/test-fstab-util.c
@@ -13,12 +13,11 @@ int fstab_filter_options(const char *opts, const char *names,
*/
static void do_fstab_filter_options(const char *opts,
- const char *remove,
- int r_expected,
- const char *name_expected,
- const char *value_expected,
- const char *filtered_expected) {
-
+ const char *remove,
+ int r_expected,
+ const char *name_expected,
+ const char *value_expected,
+ const char *filtered_expected) {
int r;
const char *name;
_cleanup_free_ char *value = NULL, *filtered = NULL;
@@ -34,7 +33,7 @@ static void do_fstab_filter_options(const char *opts,
/* also test the malloc-less mode */
r = fstab_filter_options(opts, remove, &name, NULL, NULL);
- log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"",
+ log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"\n-",
opts, r, name,
r_expected, name_expected);
assert_se(r == r_expected);
@@ -54,6 +53,12 @@ static void test_fstab_filter_options(void) {
do_fstab_filter_options("opt,other", "x-opt\0opt\0", 1, "opt", NULL, "other");
do_fstab_filter_options("x-opt,other", "opt\0x-opt\0", 1, "x-opt", NULL, "other");
+ do_fstab_filter_options("opt=0\\,1,other", "opt\0x-opt\0", 1, "opt", "0,1", "other");
+ do_fstab_filter_options("opt=0,other,x-opt\\,foobar", "x-opt\0opt\0", 1, "opt", "0", "other,x-opt\\,foobar");
+ do_fstab_filter_options("opt,other,x-opt\\,part", "opt\0x-opt\0", 1, "opt", NULL, "other,x-opt\\,part");
+ do_fstab_filter_options("opt,other,part\\,x-opt", "x-opt\0opt\0", 1, "opt", NULL, "other,part\\,x-opt");
+ do_fstab_filter_options("opt,other\\,\\,\\,opt,x-part", "opt\0x-opt\0", 1, "opt", NULL, "other\\,\\,\\,opt,x-part");
+
do_fstab_filter_options("opto=0,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
do_fstab_filter_options("opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
do_fstab_filter_options("x-opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);