Re: [PATCH 1/4] param: Move function next_arg to lib/cmdline.c for later reuse

Kees Cook
2017-04-18T20:17:53Z

On Mon, Apr 17, 2017 at 6:34 AM, Baoquan He <bhe@redhat.com> wrote:
> next_arg will be used to parse cmdline in x86/boot/compressed code,
> so move it to lib/cmdline.c for better code reuse.
>
> No change in functionality.
>
> Signed-off-by: Baoquan He <bhe@redhat.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Jessica Yu <jeyu@redhat.com>
> Cc: Petr Mladek <pmladek@suse.com>
> Cc: Jens Axboe <axboe@fb.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> Cc: zijun_hu <zijun_hu@htc.com>
> Cc: Larry Finger <Larry.Finger@lwfinger.net>
> Cc: Johannes Berg <johannes.berg@intel.com>
> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> Cc: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> Cc: "Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>
> Cc: Peter Zijlstra <peterz@infradead.org>

Acked-by: Kees Cook <keescook@chromium.org>

-Kees

> ---
> include/linux/kernel.h | 1 +
> kernel/params.c | 52 ---------------------------------------------
> lib/cmdline.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 58 insertions(+), 52 deletions(-)
>
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 4c26dc3..7ae2567 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -438,6 +438,7 @@ extern int get_option(char **str, int *pint);
> extern char *get_options(const char *str, int nints, int *ints);
> extern unsigned long long memparse(const char *ptr, char **retptr);
> extern bool parse_option_str(const char *str, const char *option);
> +extern char *next_arg(char *args, char **param, char **val);
>
> extern int core_kernel_text(unsigned long addr);
> extern int core_kernel_data(unsigned long addr);
> diff --git a/kernel/params.c b/kernel/params.c
> index a6d6149..60b2d81 100644
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -160,58 +160,6 @@ static int parse_one(char *param,
> return -ENOENT;
> }
>
> -/* You can use " around spaces, but can't escape ". */
> -/* Hyphens and underscores equivalent in parameter names. */
> -static char *next_arg(char *args, char **param, char **val)
> -{
> - unsigned int i, equals = 0;
> - int in_quote = 0, quoted = 0;
> - char *next;
> -
> - if (*args == '"') {
> - args++;
> - in_quote = 1;
> - quoted = 1;
> - }
> -
> - for (i = 0; args[i]; i++) {
> - if (isspace(args[i]) && !in_quote)
> - break;
> - if (equals == 0) {
> - if (args[i] == '=')
> - equals = i;
> - }
> - if (args[i] == '"')
> - in_quote = !in_quote;
> - }
> -
> - *param = args;
> - if (!equals)
> - *val = NULL;
> - else {
> - args[equals] = '\0';
> - *val = args + equals + 1;
> -
> - /* Don't include quotes in value. */
> - if (**val == '"') {
> - (*val)++;
> - if (args[i-1] == '"')
> - args[i-1] = '\0';
> - }
> - }
> - if (quoted && args[i-1] == '"')
> - args[i-1] = '\0';
> -
> - if (args[i]) {
> - args[i] = '\0';
> - next = args + i + 1;
> - } else
> - next = args + i;
> -
> - /* Chew up trailing spaces. */
> - return skip_spaces(next);
> -}
> -
> /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
> char *parse_args(const char *doing,
> char *args,
> diff --git a/lib/cmdline.c b/lib/cmdline.c
> index 8f13cf7..6e3abfb 100644
> --- a/lib/cmdline.c
> +++ b/lib/cmdline.c
> @@ -15,6 +15,7 @@
> #include <linux/export.h>
> #include <linux/kernel.h>
> #include <linux/string.h>
> +#include <linux/ctype.h>
>
> /*
> * If a hyphen was found in get_option, this will handle the
> @@ -189,3 +190,59 @@ bool parse_option_str(const char *str, const char *option)
>
> return false;
> }
> +
> +/*
> + * Parse a string to get a param value pair.
> + * You can use " around spaces, but can't escape ".
> + * Hyphens and underscores equivalent in parameter names.
> + */
> +char *next_arg(char *args, char **param, char **val)
> +{
> + unsigned int i, equals = 0;
> + int in_quote = 0, quoted = 0;
> + char *next;
> +
> + if (*args == '"') {
> + args++;
> + in_quote = 1;
> + quoted = 1;
> + }
> +
> + for (i = 0; args[i]; i++) {
> + if (isspace(args[i]) && !in_quote)
> + break;
> + if (equals == 0) {
> + if (args[i] == '=')
> + equals = i;
> + }
> + if (args[i] == '"')
> + in_quote = !in_quote;
> + }
> +
> + *param = args;
> + if (!equals)
> + *val = NULL;
> + else {
> + args[equals] = '\0';
> + *val = args + equals + 1;
> +
> + /* Don't include quotes in value. */
> + if (**val == '"') {
> + (*val)++;
> + if (args[i-1] == '"')
> + args[i-1] = '\0';
> + }
> + }
> + if (quoted && args[i-1] == '"')
> + args[i-1] = '\0';
> +
> + if (args[i]) {
> + args[i] = '\0';
> + next = args + i + 1;
> + } else
> + next = args + i;
> +
> + /* Chew up trailing spaces. */
> + return skip_spaces(next);
> + //return next;
> +}
> --
> 2.5.5
>

--
Kees Cook
Pixel Security