| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- From 0b7f51014f5219ece1ca55662495bd036f3bd00d Mon Sep 17 00:00:00 2001
- From: Tom Lendacky <[email protected]>
- Date: Mon, 17 Jul 2017 16:10:33 -0500
- Subject: [PATCH 049/242] x86/boot: Add early cmdline parsing for options with
- arguments
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- CVE-2017-5754
- Add a cmdline_find_option() function to look for cmdline options that
- take arguments. The argument is returned in a supplied buffer and the
- argument length (regardless of whether it fits in the supplied buffer)
- is returned, with -1 indicating not found.
- Signed-off-by: Tom Lendacky <[email protected]>
- Reviewed-by: Thomas Gleixner <[email protected]>
- Cc: Alexander Potapenko <[email protected]>
- Cc: Andrey Ryabinin <[email protected]>
- Cc: Andy Lutomirski <[email protected]>
- Cc: Arnd Bergmann <[email protected]>
- Cc: Borislav Petkov <[email protected]>
- Cc: Brijesh Singh <[email protected]>
- Cc: Dave Young <[email protected]>
- Cc: Dmitry Vyukov <[email protected]>
- Cc: Jonathan Corbet <[email protected]>
- Cc: Konrad Rzeszutek Wilk <[email protected]>
- Cc: Larry Woodman <[email protected]>
- Cc: Linus Torvalds <[email protected]>
- Cc: Matt Fleming <[email protected]>
- Cc: Michael S. Tsirkin <[email protected]>
- Cc: Paolo Bonzini <[email protected]>
- Cc: Peter Zijlstra <[email protected]>
- Cc: Radim Krčmář <[email protected]>
- Cc: Rik van Riel <[email protected]>
- Cc: Toshimitsu Kani <[email protected]>
- Cc: [email protected]
- Cc: [email protected]
- Cc: [email protected]
- Cc: [email protected]
- Cc: [email protected]
- Cc: [email protected]
- Link: http://lkml.kernel.org/r/36b5f97492a9745dce27682305f990fc20e5cf8a.1500319216.git.thomas.lendacky@amd.com
- Signed-off-by: Ingo Molnar <[email protected]>
- (cherry picked from commit e505371dd83963caae1a37ead9524e8d997341be)
- Signed-off-by: Andy Whitcroft <[email protected]>
- (cherry picked from commit 37569cd003aa69a57d5666530436c2d973a57b26)
- Signed-off-by: Andy Whitcroft <[email protected]>
- Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
- (cherry picked from commit b9f03418aa9b8ecbb1c7f32ac2bfe68fd21de4f5)
- Signed-off-by: Fabian Grünbichler <[email protected]>
- ---
- arch/x86/include/asm/cmdline.h | 2 +
- arch/x86/lib/cmdline.c | 105 +++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 107 insertions(+)
- diff --git a/arch/x86/include/asm/cmdline.h b/arch/x86/include/asm/cmdline.h
- index e01f7f7ccb0c..84ae170bc3d0 100644
- --- a/arch/x86/include/asm/cmdline.h
- +++ b/arch/x86/include/asm/cmdline.h
- @@ -2,5 +2,7 @@
- #define _ASM_X86_CMDLINE_H
-
- int cmdline_find_option_bool(const char *cmdline_ptr, const char *option);
- +int cmdline_find_option(const char *cmdline_ptr, const char *option,
- + char *buffer, int bufsize);
-
- #endif /* _ASM_X86_CMDLINE_H */
- diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c
- index 5cc78bf57232..3261abb21ef4 100644
- --- a/arch/x86/lib/cmdline.c
- +++ b/arch/x86/lib/cmdline.c
- @@ -104,7 +104,112 @@ __cmdline_find_option_bool(const char *cmdline, int max_cmdline_size,
- return 0; /* Buffer overrun */
- }
-
- +/*
- + * Find a non-boolean option (i.e. option=argument). In accordance with
- + * standard Linux practice, if this option is repeated, this returns the
- + * last instance on the command line.
- + *
- + * @cmdline: the cmdline string
- + * @max_cmdline_size: the maximum size of cmdline
- + * @option: option string to look for
- + * @buffer: memory buffer to return the option argument
- + * @bufsize: size of the supplied memory buffer
- + *
- + * Returns the length of the argument (regardless of if it was
- + * truncated to fit in the buffer), or -1 on not found.
- + */
- +static int
- +__cmdline_find_option(const char *cmdline, int max_cmdline_size,
- + const char *option, char *buffer, int bufsize)
- +{
- + char c;
- + int pos = 0, len = -1;
- + const char *opptr = NULL;
- + char *bufptr = buffer;
- + enum {
- + st_wordstart = 0, /* Start of word/after whitespace */
- + st_wordcmp, /* Comparing this word */
- + st_wordskip, /* Miscompare, skip */
- + st_bufcpy, /* Copying this to buffer */
- + } state = st_wordstart;
- +
- + if (!cmdline)
- + return -1; /* No command line */
- +
- + /*
- + * This 'pos' check ensures we do not overrun
- + * a non-NULL-terminated 'cmdline'
- + */
- + while (pos++ < max_cmdline_size) {
- + c = *(char *)cmdline++;
- + if (!c)
- + break;
- +
- + switch (state) {
- + case st_wordstart:
- + if (myisspace(c))
- + break;
- +
- + state = st_wordcmp;
- + opptr = option;
- + /* fall through */
- +
- + case st_wordcmp:
- + if ((c == '=') && !*opptr) {
- + /*
- + * We matched all the way to the end of the
- + * option we were looking for, prepare to
- + * copy the argument.
- + */
- + len = 0;
- + bufptr = buffer;
- + state = st_bufcpy;
- + break;
- + } else if (c == *opptr++) {
- + /*
- + * We are currently matching, so continue
- + * to the next character on the cmdline.
- + */
- + break;
- + }
- + state = st_wordskip;
- + /* fall through */
- +
- + case st_wordskip:
- + if (myisspace(c))
- + state = st_wordstart;
- + break;
- +
- + case st_bufcpy:
- + if (myisspace(c)) {
- + state = st_wordstart;
- + } else {
- + /*
- + * Increment len, but don't overrun the
- + * supplied buffer and leave room for the
- + * NULL terminator.
- + */
- + if (++len < bufsize)
- + *bufptr++ = c;
- + }
- + break;
- + }
- + }
- +
- + if (bufsize)
- + *bufptr = '\0';
- +
- + return len;
- +}
- +
- int cmdline_find_option_bool(const char *cmdline, const char *option)
- {
- return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option);
- }
- +
- +int cmdline_find_option(const char *cmdline, const char *option, char *buffer,
- + int bufsize)
- +{
- + return __cmdline_find_option(cmdline, COMMAND_LINE_SIZE, option,
- + buffer, bufsize);
- +}
- --
- 2.14.2
|