diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-02-13 20:40:42 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-02-14 11:13:45 +0000 |
commit | 76a286530a8b5bdbab81c3851b851dea2da32114 (patch) | |
tree | dbdd17ee66f496fa89dbf8ae0854b6031474b9ed /src/core | |
parent | 3c83843e111ece30d3dfb5143d5e6aed6164d587 (diff) | |
download | ipxe-76a286530a8b5bdbab81c3851b851dea2da32114.tar.gz |
[image] Check delimiters when parsing command-line key-value arguments
The Linux kernel bzImage image format and the CPIO archive constructor
will parse the image command line for certain arguments of the form
"key=value". This parsing is currently implemented using strstr() in
a way that can cause a false positive suffix match. For example, a
command line containing "highmem=<n>" would erroneously be treated as
containing a value for "mem=<n>".
Fix by centralising the logic used for parsing such arguments, and
including a check that the argument immediately follows a whitespace
delimiter (or is at the start of the string).
Reported-by: Filippo Giunchedi <filippo@esaurito.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/cpio.c | 9 | ||||
-rw-r--r-- | src/core/image.c | 31 |
2 files changed, 33 insertions, 7 deletions
diff --git a/src/core/cpio.c b/src/core/cpio.c index 27aee7581..4b607e260 100644 --- a/src/core/cpio.c +++ b/src/core/cpio.c @@ -77,17 +77,12 @@ size_t cpio_name_len ( struct image *image ) { */ static void cpio_parse_cmdline ( struct image *image, struct cpio_header *cpio ) { - const char *cmdline; - char *arg; + const char *arg; char *end; unsigned int mode; - /* Skip image filename */ - cmdline = ( cpio_name ( image ) + cpio_name_len ( image ) ); - /* Look for "mode=" */ - if ( ( arg = strstr ( cmdline, "mode=" ) ) ) { - arg += 5; + if ( ( arg = image_argument ( image, "mode=" ) ) ) { mode = strtoul ( arg, &end, 8 /* Octal for file mode */ ); if ( *end && ( *end != ' ' ) ) { DBGC ( image, "CPIO %p strange \"mode=\" " diff --git a/src/core/image.c b/src/core/image.c index 3e236ca60..f6d3d8ddd 100644 --- a/src/core/image.c +++ b/src/core/image.c @@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <ctype.h> #include <errno.h> #include <assert.h> #include <libgen.h> @@ -569,3 +570,33 @@ struct image * image_memory ( const char *name, userptr_t data, size_t len ) { err_alloc_image: return NULL; } + +/** + * Find argument within image command line + * + * @v image Image + * @v key Argument search key (including trailing delimiter) + * @ret value Argument value, or NULL if not found + */ +const char * image_argument ( struct image *image, const char *key ) { + const char *cmdline = image->cmdline; + const char *search; + const char *match; + const char *next; + + /* Find argument */ + for ( search = cmdline ; search ; search = next ) { + + /* Find next occurrence, if any */ + match = strstr ( search, key ); + if ( ! match ) + break; + next = ( match + strlen ( key ) ); + + /* Check preceding delimiter, if any */ + if ( ( match == cmdline ) || isspace ( match[-1] ) ) + return next; + } + + return NULL; +} |