zipl: move and make check for maximum command line length dynamic

The maximum command line length is now dependent on the kernel image
that is loaded. Therefore move the check to check_common_ipl_data().
This function now reads the new kernel image, and check whether the
command line length is in the allowed range.

The command line size limit in zipl is now set to 64k, which is hopefully
enough.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Sven Schnelle
2021-11-08 10:31:35 +01:00
committed by Jan Höppner
parent 69c5ee2e52
commit 11b401b599
2 changed files with 24 additions and 13 deletions

View File

@@ -23,7 +23,8 @@
#define ADDRESS_LIMIT 0x80000000UL
#define UNSPECIFIED_ADDRESS -1UL
#define MAXIMUM_PARMLINE_SIZE 0x380UL
#define LEGACY_MAXIMUM_PARMLINE_SIZE 0x380UL
#define MAXIMUM_PARMLINE_SIZE 0x10000UL
#define MAXIMUM_PHYSICAL_BLOCKSIZE 0x1000UL
#define BOOTMAP_FILENAME "bootmap"

View File

@@ -758,15 +758,36 @@ static void error_text_section(const char *text, const char *section, const char
static int
check_common_ipl_data(struct job_common_ipl_data *common, const char *section)
{
uint64_t max_parm_size, len;
char *buffer = NULL;
size_t size;
int rc;
if (common->image != NULL) {
rc = misc_check_readable_file(common->image);
rc = misc_read_file(common->image, &buffer, &size, 0);
if (rc) {
error_text_section("Image file", section, common->image);
return rc;
}
if (size < MAX_COMMAND_LINE_SIZE + sizeof(uint64_t)) {
error_text_section("Image file", section, common->image);
return -1;
}
max_parm_size = *(uint64_t *)(buffer + MAX_COMMAND_LINE_SIZE);
if (!max_parm_size)
max_parm_size = LEGACY_MAXIMUM_PARMLINE_SIZE;
len = strlen(common->parmline);
if (len > max_parm_size) {
error_text("The length of the parameters line "
"(%d bytes) exceeds the allowed maximum "
"(%d bytes) in section '%s'", len, max_parm_size, section);
return -1;
}
}
if (common->ramdisk != NULL) {
rc = misc_check_readable_file(common->ramdisk);
if (rc) {
@@ -1152,17 +1173,6 @@ get_parmline(char* filename, char* line, char** parmline, address_t* address,
return -1;
} else result = NULL;
/* Check for maximum length */
if (result) {
len = strlen(result);
if (len > MAXIMUM_PARMLINE_SIZE) {
error_text("The length of the parameters line "
"(%d bytes) exceeds the allowed maximum "
"(%d bytes)", len, MAXIMUM_PARMLINE_SIZE);
free(result);
return -1;
}
}
*parmline = result;
*address = addr;
return 0;