]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: Preserve empty string value in optstr parsing
authorFilipe Brandenburger <filbranden@google.com>
Wed, 10 Aug 2016 20:27:07 +0000 (13:27 -0700)
committerKarel Zak <kzak@redhat.com>
Thu, 11 Aug 2016 08:36:25 +0000 (10:36 +0200)
Recent mount (since the switch to libmount in v2.22) drops the '=' in
mount options that are set to an empty value.  For example, the command
line below will be affected:

  # mount -o rw,myopt='' -t tmpfs tmpfs /mnt/tmp

Fix that by preserving an empty string in the options passed to the
mount(2) syscall when they are present on the command line.

Add test cases to ensure empty string handling is working as expected
and in order to prevent regressions in the future.

Also tested manually by stracing mount commands (on a kernel which
accepts a special extra option, for testing purposes.)

Before this commit:

  # strace -e mount ./mount -t tmpfs -o rw,myopt='' tmpfs /mnt/tmp
  mount("tmpfs", "/mnt/tmp", "tmpfs", MS_MGC_VAL, "myarg") = -1 EINVAL (Invalid argument)

After this commit:

  # strace -e mount ./mount -t tmpfs -o rw,myopt='' tmpfs /mnt/tmp
  mount("tmpfs", "/mnt/tmp", "tmpfs", MS_MGC_VAL, "myopt=") = 0

All test cases pass, including newly added test cases.  Also checked
them with valgrind using:

  $ tests/run.sh --memcheck libmount/optstr

Fixes #332.

Signed-off-by: Filipe Brandenburger <filbranden@google.com>
libmount/src/optstr.c
tests/expected/libmount/optstr-append-empty-value [new file with mode: 0644]
tests/expected/libmount/optstr-deduplicate-empty [new file with mode: 0644]
tests/expected/libmount/optstr-prepend-empty-value [new file with mode: 0644]
tests/expected/libmount/optstr-remove-empty-value [new file with mode: 0644]
tests/expected/libmount/optstr-set-empty [new file with mode: 0644]
tests/expected/libmount/optstr-set-new-empty [new file with mode: 0644]
tests/expected/libmount/optstr-set-new-end-empty [new file with mode: 0644]
tests/ts/libmount/optstr

index b342b5f07e57e9afc11da98be0989070f2fe3fa3..9dfab67f33e4817cfb6dad3fe3d12b2be3cc3d3c 100644 (file)
@@ -185,7 +185,7 @@ static int __mnt_optstr_append_option(char **optstr,
        sz = osz + nsz + 1;             /* 1: '\0' */
        if (osz)
                sz++;                   /* ',' options separator */
-       if (vsz)
+       if (value)
                sz += vsz + 1;          /* 1: '=' */
 
        p = realloc(*optstr, sz);
@@ -201,7 +201,7 @@ static int __mnt_optstr_append_option(char **optstr,
        memcpy(p, name, nsz);
        p += nsz;
 
-       if (vsz) {
+       if (value) {
                *p++ = '=';
                memcpy(p, value, vsz);
                p += vsz;
diff --git a/tests/expected/libmount/optstr-append-empty-value b/tests/expected/libmount/optstr-append-empty-value
new file mode 100644 (file)
index 0000000..35adf5c
--- /dev/null
@@ -0,0 +1 @@
+result: >aaa,bbb=BBB,ccc,ddd=<
diff --git a/tests/expected/libmount/optstr-deduplicate-empty b/tests/expected/libmount/optstr-deduplicate-empty
new file mode 100644 (file)
index 0000000..63b74f6
--- /dev/null
@@ -0,0 +1 @@
+result: >bbb,ccc,xxx,ddd,AAA=,fff=eee<
diff --git a/tests/expected/libmount/optstr-prepend-empty-value b/tests/expected/libmount/optstr-prepend-empty-value
new file mode 100644 (file)
index 0000000..4cea635
--- /dev/null
@@ -0,0 +1 @@
+result: >ddd=,aaa,bbb=BBB,ccc<
diff --git a/tests/expected/libmount/optstr-remove-empty-value b/tests/expected/libmount/optstr-remove-empty-value
new file mode 100644 (file)
index 0000000..eee5c95
--- /dev/null
@@ -0,0 +1 @@
+result: >aaa,ccc<
diff --git a/tests/expected/libmount/optstr-set-empty b/tests/expected/libmount/optstr-set-empty
new file mode 100644 (file)
index 0000000..e0a3300
--- /dev/null
@@ -0,0 +1 @@
+result: >aaa,bbb=,ccc<
diff --git a/tests/expected/libmount/optstr-set-new-empty b/tests/expected/libmount/optstr-set-new-empty
new file mode 100644 (file)
index 0000000..a1cfb37
--- /dev/null
@@ -0,0 +1 @@
+result: >aaa=,bbb=BBB,ccc<
diff --git a/tests/expected/libmount/optstr-set-new-end-empty b/tests/expected/libmount/optstr-set-new-end-empty
new file mode 100644 (file)
index 0000000..d0e9880
--- /dev/null
@@ -0,0 +1 @@
+result: >aaa,bbb=BBB,ccc=<
index 7de299dbee05ef31dfcc3cf07b20993ac31a8d0e..1fbf0641c7f96eec262fa75ae5064641b57e2bbc 100755 (executable)
@@ -20,6 +20,10 @@ ts_init_subtest "append-value"
 ts_valgrind $TESTPROG --append "aaa,bbb=BBB,ccc" "ddd" "DDD" &> $TS_OUTPUT
 ts_finalize_subtest
 
+ts_init_subtest "append-empty-value"
+ts_valgrind $TESTPROG --append "aaa,bbb=BBB,ccc" "ddd" "" &> $TS_OUTPUT
+ts_finalize_subtest
+
 ts_init_subtest "prepend"
 ts_valgrind $TESTPROG --prepend "aaa,bbb=BBB,ccc" "ddd" &> $TS_OUTPUT
 ts_finalize_subtest
@@ -28,6 +32,10 @@ ts_init_subtest "prepend-value"
 ts_valgrind $TESTPROG --prepend "aaa,bbb=BBB,ccc" "ddd" "DDD" &> $TS_OUTPUT
 ts_finalize_subtest
 
+ts_init_subtest "prepend-empty-value"
+ts_valgrind $TESTPROG --prepend "aaa,bbb=BBB,ccc" "ddd" "" &> $TS_OUTPUT
+ts_finalize_subtest
+
 ts_init_subtest "set-remove"
 ts_valgrind $TESTPROG --set "aaa,bbb=BBB,ccc" "bbb" &> $TS_OUTPUT
 ts_finalize_subtest
@@ -40,14 +48,26 @@ ts_init_subtest "set-large"
 ts_valgrind $TESTPROG --set "aaa,bbb=BBB,ccc" "bbb" "XXX-YYY-ZZZ" &> $TS_OUTPUT
 ts_finalize_subtest
 
+ts_init_subtest "set-empty"
+ts_valgrind $TESTPROG --set "aaa,bbb=BBB,ccc" "bbb" "" &> $TS_OUTPUT
+ts_finalize_subtest
+
 ts_init_subtest "set-new"
 ts_valgrind $TESTPROG --set "aaa,bbb=BBB,ccc" "aaa" "XXX" &> $TS_OUTPUT
 ts_finalize_subtest
 
+ts_init_subtest "set-new-empty"
+ts_valgrind $TESTPROG --set "aaa,bbb=BBB,ccc" "aaa" "" &> $TS_OUTPUT
+ts_finalize_subtest
+
 ts_init_subtest "set-new-end"
 ts_valgrind $TESTPROG --set "aaa,bbb=BBB,ccc" "ccc" "XXX" &> $TS_OUTPUT
 ts_finalize_subtest
 
+ts_init_subtest "set-new-end-empty"
+ts_valgrind $TESTPROG --set "aaa,bbb=BBB,ccc" "ccc" "" &> $TS_OUTPUT
+ts_finalize_subtest
+
 ts_init_subtest "get"
 ts_valgrind $TESTPROG --get "aaa,bbb=BBB,ccc" "aaa" &> $TS_OUTPUT
 ts_finalize_subtest
@@ -68,6 +88,10 @@ ts_init_subtest "remove-value"
 ts_valgrind $TESTPROG --remove "aaa,bbb=BBB,ccc" "bbb" &> $TS_OUTPUT
 ts_finalize_subtest
 
+ts_init_subtest "remove-empty-value"
+ts_valgrind $TESTPROG --remove "aaa,bbb=,ccc" "bbb" &> $TS_OUTPUT
+ts_finalize_subtest
+
 ts_init_subtest "split"
 ts_valgrind $TESTPROG --split "aaa,bbb=BBB,ccc,x-bar,x-foo=foodata,user=kzak,noexec,nosuid,loop=/dev/loop0" &> $TS_OUTPUT
 ts_finalize_subtest
@@ -92,4 +116,8 @@ ts_init_subtest "deduplicate"
 ts_valgrind $TESTPROG --dedup bbb,ccc,AAA,xxx,AAA=a,AAA=bbb,ddd,AAA=ccc,fff=eee AAA &> $TS_OUTPUT
 ts_finalize_subtest
 
+ts_init_subtest "deduplicate-empty"
+ts_valgrind $TESTPROG --dedup bbb,ccc,AAA,xxx,AAA=a,AAA=bbb,ddd,AAA=,fff=eee AAA &> $TS_OUTPUT
+ts_finalize_subtest
+
 ts_finalize