zipl/src: Fix problems when target parameters are specified by user

Steps to reproduce: Prepare some target disk for IPL, specifying
its parameters via zipl "target options", and an image IMAGE_NAME
located on another disk. Don't specify "-a" option.

Actual result: Installation succeeded (resulting in unbootable setup)
Expected result: "Error: Could not add image file 'IMAGE_NAME': File
is not on target device"

The problem is in incorrect evaluation of device number(dev_t) where
the image is located by the function add_component_file_range() in
case when target parameters are specified by user.

Fixup: Retrieve info of the underlying disk without any user hints,
passing zeroed structure job_target_data

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
Eduard Shishkin
2024-05-01 22:23:15 +02:00
committed by Steffen Eiden
parent 76aaf3d4a8
commit fb0b6263d1
4 changed files with 26 additions and 21 deletions

View File

@@ -152,6 +152,7 @@ static inline int target_parameters_are_set(struct job_target_data *td)
int job_get(int argc, char* argv[], struct job_data** data);
void job_free(struct job_data* job);
void free_target_data(struct job_target_data *td);
int type_from_target(char *target, disk_type_t *type);
int check_job_dump_images(struct job_dump_data* dump, char* name);
int check_job_images_ngdump(struct job_dump_data* dump, char* name);

View File

@@ -304,7 +304,6 @@ static int add_component_file_range(struct install_set *bis,
address_t load_address,
size_t trailer, void *component,
int add_files,
struct job_target_data *target,
int comp_id, int menu_idx,
int program_table_id)
{
@@ -339,8 +338,15 @@ static int add_component_file_range(struct install_set *bis,
return -1;
}
} else {
/* Make sure file is on correct device */
rc = disk_get_info_from_file(filename, target, &file_info);
/*
* Make sure that file is on target device.
* For this, retrieve info of the underlying disk without
* any user hints
*/
struct job_target_data tmp = {.source = source_unknown};
rc = disk_get_info_from_file(filename, &tmp, &file_info);
free_target_data(&tmp);
if (rc)
return -1;
if (file_info->device != bis->info->device) {
@@ -377,12 +383,11 @@ write_segment_table:
static int add_component_file(struct install_set *bis, const char *filename,
address_t load_address, size_t trailer,
void *component, int add_files,
struct job_target_data *target, int comp_id,
int menu_idx, int program_table_id)
int comp_id, int menu_idx, int program_table_id)
{
return add_component_file_range(bis, filename, NULL, load_address,
trailer, component, add_files,
target, comp_id, menu_idx,
comp_id, menu_idx,
program_table_id);
}
@@ -544,8 +549,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
bool add_envblk, struct job_envblk_data *envblk,
struct job_ipl_data *ipl, disk_blockptr_t *program,
int verbose, int add_files, component_header_type type,
struct job_target_data *target, int is_secure,
int menu_idx, int program_table_id)
int is_secure, int menu_idx, int program_table_id)
{
struct signature_header sig_head;
size_t ramdisk_size, image_size;
@@ -667,7 +671,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
/* Add stage 3 loader to bootmap */
rc = add_component_file(bis, ZIPL_STAGE3_PATH, STAGE3_LOAD_ADDRESS,
signature_size, VOID_ADD(table, offset), 1,
target, COMPONENT_ID_LOADER, menu_idx,
COMPONENT_ID_LOADER, menu_idx,
program_table_id);
if (rc) {
error_text("Could not add internal loader file '%s'",
@@ -745,7 +749,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
rc = add_component_file(bis, ipl->common.image, ipl->common.image_addr,
signature_size, VOID_ADD(table, offset),
add_files, target, COMPONENT_ID_KERNEL_IMAGE,
add_files, COMPONENT_ID_KERNEL_IMAGE,
menu_idx, program_table_id);
if (rc) {
error_text("Could not add image file '%s'", ipl->common.image);
@@ -805,7 +809,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
ipl->common.ramdisk_addr,
signature_size,
VOID_ADD(table, offset),
add_files, target, COMPONENT_ID_RAMDISK,
add_files, COMPONENT_ID_RAMDISK,
menu_idx, program_table_id);
if (rc) {
error_text("Could not add ramdisk '%s'",
@@ -861,7 +865,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
rc = add_component_file_range(bis, filename, &reg,
ipl->envblk_addr, 0,
VOID_ADD(table, offset),
0, target,
0,
COMPONENT_ID_ENVBLK,
menu_idx,
program_table_id);
@@ -893,7 +897,6 @@ static int add_segment_program(struct install_set *bis,
struct job_segment_data *segment,
disk_blockptr_t *program, int verbose,
int add_files, component_header_type type,
struct job_target_data *target,
int program_table_id)
{
void *table;
@@ -913,7 +916,7 @@ static int add_segment_program(struct install_set *bis,
printf(" segment file......: %s\n", segment->segment);
rc = add_component_file(bis, segment->segment, segment->segment_addr, 0,
VOID_ADD(table, offset), add_files, target,
VOID_ADD(table, offset), add_files,
COMPONENT_ID_SEGMENT_FILE, 0 /* menu_idx */,
program_table_id);
if (rc) {
@@ -996,7 +999,7 @@ static int add_dump_program(struct install_set *bis, struct job_data *job,
ipl.common.parmline = dump->common.parmline;
ipl.common.parm_addr = dump->common.parm_addr;
return add_ipl_program(bis, NULL, false, NULL, &ipl, program,
verbose, 1, type, target, SECURE_BOOT_DISABLED,
verbose, 1, type, SECURE_BOOT_DISABLED,
0 /* menu_idx */, program_table_id);
}
@@ -1041,8 +1044,7 @@ static int build_program_table(struct job_data *job,
true, &job->envblk, &job->data.ipl,
&table[0], verbose || job->command_line,
job->add_files, component_header,
&job->target, job->is_secure, 0,
program_table_id);
job->is_secure, 0, program_table_id);
break;
case job_segment:
if (bis->print_details) {
@@ -1055,7 +1057,7 @@ static int build_program_table(struct job_data *job,
rc = add_segment_program(bis, &job->data.segment, &table[0],
verbose || job->command_line,
job->add_files, COMPONENT_HEADER_IPL,
&job->target, program_table_id);
program_table_id);
break;
case job_dump_partition:
/* Only useful for a partition dump that uses a dump kernel*/
@@ -1114,7 +1116,7 @@ static int build_program_table(struct job_data *job,
&table[job->data.menu.entry[i].pos],
verbose || job->command_line,
job->add_files, component_header,
&job->target, is_secure, i,
is_secure, i,
program_table_id);
break;
case job_print_usage:

View File

@@ -528,6 +528,9 @@ static int disk_set_info_complete(struct job_target_data *td,
* config file, or special "target options" of zipl tool.
* If target parameters were specified by user, then the step 1 above
* is skipped.
* To exclude any user assumptions about the DEVICE, this function
* should be called with TD pointing to a zeroed structure.
*
* DEVICE: logical, or physical device, optionally formated with a
* file system.

View File

@@ -370,8 +370,7 @@ get_command_line(int argc, char* argv[], struct command_line* line)
}
static void
free_target_data(struct job_target_data* data)
void free_target_data(struct job_target_data *data)
{
free(data->bootmap_dir);
free(data->targetbase);