mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl/boot: Fix undefined behaviour logic in menu
The code within 'menu_param()' previously assumed that a read from sclp
will never fail.
If 'sclp_param()' fails then 'endptr' is never initialised and
'loadparm' is compared with 'endptr' which is undefined behvaiour.
If a sclp read fails, an undefined 'endptr' is never accessed, and upon
a failed read, will return a new error code 'SCLP_ERROR' instead of
returning 'NUMBER_FOUND' which is incorrect logic wise.
Remove compare conditions and assignments of 0 in 'value', as 'value'
is initialised with 0 ('DEFAULT_MENU_ENTRY') and cannot be non zero,
only in the case where a number is found and we go to boot.
Logic:
Check if we got a number and boot from it.
If 'PRINT_PROMPT', break out to menu print logic.
If an 'SCLP_ERROR' occurs, print an error message and boot the default
since 'value' is initialised with 'DEFAULT_MENU_ENTRY'.
If 'NOTHING_FOUND', check if the menu is disabled. If disabled, go to
default boot. Otherwise break out to print logic.
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Richie Buturla <richie@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
4a9f66fc31
commit
20a4ebd83c
+27
-16
@@ -102,6 +102,7 @@ enum param_result {
|
|||||||
NUMBER_FOUND = 0,
|
NUMBER_FOUND = 0,
|
||||||
PRINT_PROMPT = 1,
|
PRINT_PROMPT = 1,
|
||||||
NOTHING_FOUND = 2,
|
NOTHING_FOUND = 2,
|
||||||
|
SCLP_ERROR = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -114,6 +115,7 @@ enum param_result {
|
|||||||
* 0 - found number to boot, stored in value
|
* 0 - found number to boot, stored in value
|
||||||
* 1 - print prompt
|
* 1 - print prompt
|
||||||
* 2 - nothing found
|
* 2 - nothing found
|
||||||
|
* 3 - sclp error
|
||||||
*/
|
*/
|
||||||
static enum param_result menu_param(unsigned long *value)
|
static enum param_result menu_param(unsigned long *value)
|
||||||
{
|
{
|
||||||
@@ -121,8 +123,12 @@ static enum param_result menu_param(unsigned long *value)
|
|||||||
char *endptr;
|
char *endptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!sclp_param(loadparm))
|
/* try to fetch loadparms from sclp into 'loadparm' */
|
||||||
*value = ebcdic_strtoul(loadparm, &endptr, 10);
|
if (sclp_param(loadparm) != 0)
|
||||||
|
return SCLP_ERROR;
|
||||||
|
|
||||||
|
/* parse number from loadparm */
|
||||||
|
*value = ebcdic_strtoul(loadparm, &endptr, 10);
|
||||||
|
|
||||||
/* got number, done */
|
/* got number, done */
|
||||||
if (endptr != loadparm)
|
if (endptr != loadparm)
|
||||||
@@ -134,39 +140,44 @@ static enum param_result menu_param(unsigned long *value)
|
|||||||
while ((i < PARAM_SIZE) && ecbdic_isspace(loadparm[i]))
|
while ((i < PARAM_SIZE) && ecbdic_isspace(loadparm[i]))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!strncmp(&loadparm[i], "PROMPT", 6)) {
|
if (!strncmp(&loadparm[i], "PROMPT", 6))
|
||||||
*value = 0;
|
|
||||||
return PRINT_PROMPT;
|
return PRINT_PROMPT;
|
||||||
}
|
|
||||||
|
|
||||||
return NOTHING_FOUND;
|
return NOTHING_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
int menu(void)
|
int menu(void)
|
||||||
{
|
{
|
||||||
unsigned long value = 0;
|
enum { DEFAULT_MENU_ENTRY = 0 };
|
||||||
|
unsigned long value = DEFAULT_MENU_ENTRY;
|
||||||
char *cmd_line_extra;
|
char *cmd_line_extra;
|
||||||
char endstring[15];
|
char endstring[15];
|
||||||
int rc;
|
|
||||||
|
|
||||||
cmd_line_extra = (char *)COMMAND_LINE_EXTRA;
|
cmd_line_extra = (char *)COMMAND_LINE_EXTRA;
|
||||||
memset(cmd_line_extra, 0, COMMAND_LINE_EXTRA_SIZE);
|
memset(cmd_line_extra, 0, COMMAND_LINE_EXTRA_SIZE);
|
||||||
|
|
||||||
rc = sclp_setup(SCLP_INIT);
|
if (sclp_setup(SCLP_INIT) != 0) {
|
||||||
if (rc)
|
|
||||||
/* sclp setup failed boot default */
|
/* sclp setup failed boot default */
|
||||||
goto boot;
|
goto boot;
|
||||||
|
}
|
||||||
|
|
||||||
rc = menu_param(&value);
|
switch (menu_param(&value)) {
|
||||||
if (rc == NUMBER_FOUND) {
|
case NUMBER_FOUND:
|
||||||
/* got number from loadparm, boot it */
|
/* got number from loadparm, boot it */
|
||||||
goto boot;
|
goto boot;
|
||||||
} else if (rc == PRINT_PROMPT && value == 0) {
|
case PRINT_PROMPT:
|
||||||
/* keyword "prompt", show menu */
|
/* print menu */
|
||||||
} else if (__stage2_params.flag == 0) {
|
break;
|
||||||
/* menu disabled, boot default */
|
case SCLP_ERROR:
|
||||||
value = 0;
|
/* failed to read from sclp, boot default */
|
||||||
|
printf("SCLP_ERROR\n");
|
||||||
goto boot;
|
goto boot;
|
||||||
|
case NOTHING_FOUND:
|
||||||
|
if (__stage2_params.flag == 0) {
|
||||||
|
/* menu disabled, boot default */
|
||||||
|
goto boot;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print banner */
|
/* print banner */
|
||||||
|
|||||||
Reference in New Issue
Block a user