mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl/src: prevent NULL pointer deref when preparing qcow2 images for IPL
This fixes c0f02d2f6 which results in problems when preparing qcow2
images for IPL:
zipl -V --blsdir /tmp/tmp.kdPooQjoBh/boot//loader/entries/ --config /
Program terminated with signal SIGFPE, Arithmetic exception.
Don't use pointer to not initialized struct disk_info after failed
auto-detection of disk parameters. Make the check that the file
locates on the disk in the form of a separate procedure.
Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
41da0f0809
commit
0e4992da3a
@@ -298,6 +298,47 @@ create_component_header(void* buffer, component_header_type type)
|
||||
header->type = (uint8_t) type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not precise check that the file FILENAME locates on specified physical DISK.
|
||||
*
|
||||
* Try to auto-detect parameters of the disk which the file locates on
|
||||
* and compare found device-ID with DISK.
|
||||
* Return 0, if auto-detection succeeded, and it is proven that the
|
||||
* file does NOT locate on DISK. Otherwise, return 1.
|
||||
*/
|
||||
static int file_is_on_disk(const char *filename, dev_t disk)
|
||||
{
|
||||
/*
|
||||
* Retrieve info of the underlying disk without any user hints
|
||||
*/
|
||||
struct job_target_data tmp = {.source = source_unknown};
|
||||
struct disk_info *info;
|
||||
int rc;
|
||||
|
||||
rc = disk_get_info_from_file(filename, &tmp, &info);
|
||||
free_target_data(&tmp);
|
||||
if (rc) {
|
||||
/*
|
||||
* In some cases it is impossible to auto-detect
|
||||
* disk parameters (e.g. when the file is on a
|
||||
* mounted qcow2 image).
|
||||
* Skip the check with warnings.
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"Warning: Could not auto-detect disk parameters for %s\n",
|
||||
filename);
|
||||
fprintf(stderr,
|
||||
"Warning: Preparing a logical device for boot might fail\n");
|
||||
return 1;
|
||||
}
|
||||
if (info->device != disk) {
|
||||
disk_free_info(info);
|
||||
return 0;
|
||||
}
|
||||
disk_free_info(info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_component_file_range(struct install_set *bis,
|
||||
const char *filename,
|
||||
struct file_range *reg,
|
||||
@@ -311,7 +352,6 @@ static int add_component_file_range(struct install_set *bis,
|
||||
struct component_loc *location = &pc->loc;
|
||||
disk_blockptr_t **list = &pc->list;
|
||||
blocknum_t *count = &pc->count;
|
||||
struct disk_info* file_info;
|
||||
disk_blockptr_t segment;
|
||||
char* buffer;
|
||||
size_t size;
|
||||
@@ -338,36 +378,13 @@ static int add_component_file_range(struct install_set *bis,
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* 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) {
|
||||
/*
|
||||
* In some cases it is impossible to auto-detect
|
||||
* disk parameters (e.g. when the file is on a
|
||||
* mounted qcow2 image).
|
||||
* Skip the check with warnings.
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"Warning: Could not auto-detect disk parameters for %s\n",
|
||||
filename);
|
||||
fprintf(stderr,
|
||||
"Warning: Preparing a logical device for boot might fail\n");
|
||||
} else if (file_info->device != bis->info->device) {
|
||||
disk_free_info(file_info);
|
||||
if (!file_is_on_disk(filename, bis->info->device)) {
|
||||
error_reason("File is not on target device");
|
||||
return -1;
|
||||
}
|
||||
/* Get block list from existing file */
|
||||
*count = disk_get_blocklist_from_file(filename, reg,
|
||||
list, file_info);
|
||||
disk_free_info(file_info);
|
||||
list, bis->info);
|
||||
if (*count == 0)
|
||||
return -1;
|
||||
*count -= DIV_ROUND_UP(trailer, bis->info->phy_block_size);
|
||||
|
||||
Reference in New Issue
Block a user