modprobe: handle module arguments containing spaces
authorPeter Korsgaard <peter@korsgaard.com>
Wed, 9 Sep 2015 12:55:07 +0000 (14:55 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 9 Sep 2015 12:55:07 +0000 (14:55 +0200)
Modprobe wasn't correctly parsing module arguments containing spaces from
/proc/cmdline - E.G. module.property="some text".

Extend the parsing to correctly handle quoted text.

Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
modutils/modprobe.c

index 996de4074cd0c885f058111d41281e170892052a..314a7a1cbea8acf2978fef0c5b59929682bbbfb3 100644 (file)
@@ -348,6 +348,38 @@ static const char *humanly_readable_name(struct module_entry *m)
        return m->probed_name ? m->probed_name : m->modname;
 }
 
+/* Like strsep(&stringp, "\n\t ") but quoted text goes to single token
+ * even if it contains whitespace.
+ */
+static char *strsep_quotes(char **stringp)
+{
+       char *s, *start = *stringp;
+
+       if (!start)
+               return NULL;
+
+       for (s = start; ; s++) {
+               switch (*s) {
+               case '"':
+                       s = strchrnul(s + 1, '"'); /* find trailing quote */
+                       if (*s != '\0')
+                               s++; /* skip trailing quote */
+                       /* fall through */
+               case '\0':
+               case '\n':
+               case '\t':
+               case ' ':
+                       if (*s != '\0') {
+                               *s = '\0';
+                               *stringp = s + 1;
+                       } else {
+                               *stringp = NULL;
+                       }
+                       return start;
+               }
+       }
+}
+
 static char *parse_and_add_kcmdline_module_options(char *options, const char *modulename)
 {
        char *kcmdline_buf;
@@ -359,7 +391,7 @@ static char *parse_and_add_kcmdline_module_options(char *options, const char *mo
                return options;
 
        kcmdline = kcmdline_buf;
-       while ((kptr = strsep(&kcmdline, "\n\t ")) != NULL) {
+       while ((kptr = strsep_quotes(&kcmdline)) != NULL) {
                char *after_modulename = is_prefixed_with(kptr, modulename);
                if (!after_modulename || *after_modulename != '.')
                        continue;