File s390-tools-sles11sp2-zipl_parmfile_addr.patch of Package s390-tools
Description: zipl: Prevent unsupported parmfile address.
Symptom: The system is not bootable after changing the parmfile address.
Problem: Zipl allows the user to specify the address for the parmfile.
But below 0x10000 there are several zipl internal
addresses used e.g. 0x2000 as entry point for the
internal loader. The usage of this addresses is not
prevented.
Solution: Block all addresses below 0x10000. Also remove default
address for the parmfile and let the address be calculated
automatically.
Problem-ID: 75229
---
zipl/include/zipl.h | 6 ++----
zipl/src/job.c | 40 +++++++++++++++++++---------------------
2 files changed, 21 insertions(+), 25 deletions(-)
--- a/zipl/include/zipl.h
+++ b/zipl/include/zipl.h
@@ -18,16 +18,14 @@
#define ZIPL_MAGIC_SIZE 4
#define DISK_LAYOUT_ID 0x00000001
-#define ZIPL_STAGE2_LOAD_ADDRESS 0x2000
+#define ZIPL_STAGE2_LOAD_ADDRESS 0x2000
#define ZIPL_STAGE3_ENTRY_ADDRESS 0xa028LL
-#define DEFAULT_PARMFILE_ADDRESS 0x1000LL
-#define DEFAULT_STAGE3_ADDRESS 0xa000LL
#define DEFAULT_IMAGE_ADDRESS 0x10000LL
+#define DEFAULT_STAGE3_ADDRESS 0xa000LL
#define MINIMUM_ADDRESS 0x10000LL
#define ADDRESS_LIMIT 0x80000000LL
#define UNSPECIFIED_ADDRESS -1ULL
#define MAXIMUM_PARMLINE_SIZE 0x380
-#define MAXIMUM_STAGE3_SIZE 0x1000
#define MAXIMUM_PHYSICAL_BLOCKSIZE 0x1000
#define PSW_ADDRESS_MASK 0x000000007fffffffLL
--- a/zipl/src/job.c
+++ b/zipl/src/job.c
@@ -24,7 +24,6 @@
#include "misc.h"
#include "scan.h"
-
/* Command line options */
static struct option options[] = {
{ "config", required_argument, NULL, 'c'},
@@ -494,14 +493,14 @@ sort_cl_array(struct component_loc* cl,
static int
get_ipl_components(struct job_ipl_data *ipl, struct component_loc **clp,
- int *nump, address_t *stage3_addrp)
+ int *nump)
{
struct component_loc *cl;
int num;
int rc;
- /* Get memory for image, parmline, ramdisk, loader */
- cl = misc_calloc(4, sizeof(struct component_loc));
+ /* Get memory for image, parmline, ramdisk */
+ cl = misc_calloc(3, sizeof(struct component_loc));
if (cl == NULL)
return -1;
/* Fill in component data */
@@ -524,10 +523,7 @@ get_ipl_components(struct job_ipl_data *
if (rc)
goto error;
}
- rc = set_cl_element(&cl[num++], "internal loader", NULL, stage3_addrp,
- MAXIMUM_STAGE3_SIZE, 0, MAXIMUM_PHYSICAL_BLOCKSIZE);
- if (rc)
- goto error;
+
*clp = cl;
*nump = num;
return 0;
@@ -539,15 +535,14 @@ error:
static int
get_dump_fs_components(struct job_dump_fs_data *dump_fs,
- struct component_loc **clp, int *nump,
- address_t *stage3_addrp)
+ struct component_loc **clp, int *nump)
{
struct component_loc *cl;
int num;
int rc;
/* Get memory for image, parmline, ramdisk, loader */
- cl = misc_calloc(4, sizeof(struct component_loc));
+ cl = misc_calloc(3, sizeof(struct component_loc));
if (cl == NULL)
return -1;
/* Fill in component data */
@@ -569,10 +564,7 @@ get_dump_fs_components(struct job_dump_f
if (rc)
goto error;
}
- rc = set_cl_element(&cl[num++], "internal loader", NULL, stage3_addrp,
- MAXIMUM_STAGE3_SIZE, 0, MAXIMUM_PHYSICAL_BLOCKSIZE);
- if (rc)
- goto error;
+
*clp = cl;
*nump = num;
return 0;
@@ -643,6 +635,14 @@ check_component_address_data(struct comp
ADDRESS_LIMIT);
return -1;
}
+ if (*cl[i].addrp < MINIMUM_ADDRESS) {
+ if (name != NULL)
+ error_text("Section '%s'", name);
+ error_reason("Component '%s' falls below available "
+ "address space (limit is 0x%08x)",
+ cl[i].name, MINIMUM_ADDRESS);
+ return -1;
+ }
}
/* Check for overlap */
for (i = 0; i < num - 1; i++) {
@@ -717,10 +717,9 @@ finalize_ipl_address_data(struct job_ipl
{
struct component_loc *cl;
int num;
- address_t stage3_addr = DEFAULT_STAGE3_ADDRESS;
int rc;
- rc = get_ipl_components(ipl, &cl, &num, &stage3_addr);
+ rc = get_ipl_components(ipl, &cl, &num);
if (rc)
return rc;
sort_cl_array(cl, num);
@@ -739,10 +738,9 @@ finalize_dump_fs_address_data(struct job
{
struct component_loc *cl;
int num;
- address_t stage3_addr = DEFAULT_STAGE3_ADDRESS;
int rc;
- rc = get_dump_fs_components(dump_fs, &cl, &num, &stage3_addr);
+ rc = get_dump_fs_components(dump_fs, &cl, &num);
if (rc)
return rc;
sort_cl_array(cl, num);
@@ -904,7 +902,7 @@ check_job_dump_fs_data(struct job_dump_f
dump_fs->ramdisk_addr = UNSPECIFIED_ADDRESS;
}
- dump_fs->parm_addr = DEFAULT_PARMFILE_ADDRESS;
+ dump_fs->parm_addr = UNSPECIFIED_ADDRESS;
return finalize_dump_fs_address_data(dump_fs, name);
}
@@ -1195,7 +1193,7 @@ get_parmline(char* filename, char* line,
int to;
int got_lf;
- addr = DEFAULT_PARMFILE_ADDRESS;
+ addr = UNSPECIFIED_ADDRESS;
if (filename != NULL) {
/* Need a filename copy to be able to change it */
filename = misc_strdup(filename);