Skip to content

Commit 1fb8105

Browse files
Michael HolzheuMartin Schwidefsky
Michael Holzheu
authored and
Martin Schwidefsky
committed
[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 <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 272f01b commit 1fb8105

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

arch/s390/kernel/early.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -434,18 +434,22 @@ static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
434434
}
435435
}
436436

437-
static void __init setup_boot_command_line(void)
437+
static inline int has_ebcdic_char(const char *str)
438438
{
439439
int i;
440440

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+
}
448446

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);
449453
/* copy arch command line */
450454
strlcpy(boot_command_line, strstrip(COMMAND_LINE),
451455
ARCH_COMMAND_LINE_SIZE);

0 commit comments

Comments
 (0)