Commit 1fb810576f0e92451a5d46774bbd593946ca3526

Authored by Michael Holzheu
Committed by Martin Schwidefsky
1 parent 272f01bf9b

[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>

Showing 1 changed file with 12 additions and 8 deletions Side-by-side Diff

arch/s390/kernel/early.c
... ... @@ -434,18 +434,22 @@
434 434 }
435 435 }
436 436  
437   -static void __init setup_boot_command_line(void)
  437 +static inline int has_ebcdic_char(const char *str)
438 438 {
439 439 int i;
440 440  
441   - /* convert arch command line to ascii */
442   - for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++)
443   - if (COMMAND_LINE[i] & 0x80)
444   - break;
445   - if (i < ARCH_COMMAND_LINE_SIZE)
446   - EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
447   - COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
  441 + for (i = 0; str[i]; i++)
  442 + if (str[i] & 0x80)
  443 + return 1;
  444 + return 0;
  445 +}
448 446  
  447 +static 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 453 /* copy arch command line */
450 454 strlcpy(boot_command_line, strstrip(COMMAND_LINE),
451 455 ARCH_COMMAND_LINE_SIZE);