aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/early.c
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2011-12-27 05:25:46 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-12-27 05:25:48 -0500
commit1fb810576f0e92451a5d46774bbd593946ca3526 (patch)
tree64916e26ab8b5773cc76d05260560a36bcf7a6a4 /arch/s390/kernel/early.c
parent272f01bf9b6da93f49fcca2656c24da8d2cfcc09 (diff)
[S390] Check for NULL termination in command line setup
The current code in setup_boot_command_line() uses a heuristic to detect an EBCDIC command line. It checks if any of the bytes in the command line has bit one (0x80) set. In that case it is assumed that we have an EBCDIC string and the complete command line is converted. On s390 there are cases where the boot loader provides a kernel command line that is NULL terminated, but has random data after the NULL termination. In that case, setup_boot_command_line() might misinterpret an ASCII string for an EBCDIC string. A subsequent string conversion can then damage the ASCII string. This patch solves the problem by checking for NULL termination. If no EBCDIC character has been found until the the NULL termination has been found, we now assume that we have an ASCII string. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/early.c')
-rw-r--r--arch/s390/kernel/early.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c9ffe0025197..52098d6dfaa7 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -434,18 +434,22 @@ static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
434 } 434 }
435} 435}
436 436
437static void __init setup_boot_command_line(void) 437static inline int has_ebcdic_char(const char *str)
438{ 438{
439 int i; 439 int i;
440 440
441 /* convert arch command line to ascii */ 441 for (i = 0; str[i]; i++)
442 for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++) 442 if (str[i] & 0x80)
443 if (COMMAND_LINE[i] & 0x80) 443 return 1;
444 break; 444 return 0;
445 if (i < ARCH_COMMAND_LINE_SIZE) 445}
446 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
447 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
448 446
447static void __init setup_boot_command_line(void)
448{
449 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE - 1] = 0;
450 /* convert arch command line to ascii if necessary */
451 if (has_ebcdic_char(COMMAND_LINE))
452 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
449 /* copy arch command line */ 453 /* copy arch command line */
450 strlcpy(boot_command_line, strstrip(COMMAND_LINE), 454 strlcpy(boot_command_line, strstrip(COMMAND_LINE),
451 ARCH_COMMAND_LINE_SIZE); 455 ARCH_COMMAND_LINE_SIZE);