forked from pool/s390-tools
188 lines
6.1 KiB
Diff
188 lines
6.1 KiB
Diff
|
Subject: [PATCH] [BZ 184396] zipl: correct secure boot config handling
|
||
|
From: Stefan Haberland <sth@linux.ibm.com>
|
||
|
|
||
|
Description: zipl: fix secure boot config handling
|
||
|
Symptom: The config file parsing for secure boot worked not as
|
||
|
it was expected to be. For example a config section
|
||
|
setting was not evaluated properly.
|
||
|
It is not possible to specify command line option -S
|
||
|
without other options.
|
||
|
Additionally the man page showed an invalid example.
|
||
|
Problem: The config file parsing was not implemented properly.
|
||
|
Solution: The hierarchy of the secure boot settings in the config
|
||
|
file is:
|
||
|
defaultboot > menu > section
|
||
|
Allow that --secure or -S is specified on command line
|
||
|
without the need to allow all options on the command
|
||
|
line. Also ensure that the command line option
|
||
|
overrules the config option and correctly ensure that
|
||
|
secure boot is only set for SCSI devices.
|
||
|
Fix man page example.
|
||
|
Reproduction: Run zipl with a secure= setting in a configuration
|
||
|
section or specify -S on command line.
|
||
|
Upstream-ID: 6f9337d1016e00f360cf4a81d39a42df5184b3a2
|
||
|
Problem-ID: 184396
|
||
|
|
||
|
Upstream-Description:
|
||
|
|
||
|
zipl: correct secure boot config handling
|
||
|
|
||
|
The hierarchy of the secure boot settings in the config file should be:
|
||
|
|
||
|
defaultboot > menu > section
|
||
|
|
||
|
This patch implements this hierarchy and adds a check if a valid option is
|
||
|
specified and prints an error message otherwise.
|
||
|
|
||
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||
|
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
|
||
|
Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
||
|
|
||
|
|
||
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||
|
---
|
||
|
zipl/include/job.h | 1 +
|
||
|
zipl/include/zipl.h | 1 +
|
||
|
zipl/src/bootmap.c | 8 +++++++-
|
||
|
zipl/src/job.c | 29 ++++++++++++++++++++++++++---
|
||
|
4 files changed, 35 insertions(+), 4 deletions(-)
|
||
|
|
||
|
--- a/zipl/include/job.h
|
||
|
+++ b/zipl/include/job.h
|
||
|
@@ -94,6 +94,7 @@ struct job_menu_entry {
|
||
|
char* name;
|
||
|
enum job_id id;
|
||
|
union job_menu_entry_data data;
|
||
|
+ int is_secure;
|
||
|
};
|
||
|
|
||
|
struct job_menu_data {
|
||
|
--- a/zipl/include/zipl.h
|
||
|
+++ b/zipl/include/zipl.h
|
||
|
@@ -57,6 +57,7 @@
|
||
|
|
||
|
#define MAX_DUMP_VOLUMES 32
|
||
|
|
||
|
+#define SECURE_BOOT_UNDEFINED -1
|
||
|
#define SECURE_BOOT_DISABLED 0
|
||
|
#define SECURE_BOOT_ENABLED 1
|
||
|
#define SECURE_BOOT_AUTO 2
|
||
|
--- a/zipl/src/bootmap.c
|
||
|
+++ b/zipl/src/bootmap.c
|
||
|
@@ -945,6 +945,7 @@ build_program_table(int fd, struct job_d
|
||
|
{
|
||
|
disk_blockptr_t* table;
|
||
|
int entries, component_header;
|
||
|
+ int is_secure;
|
||
|
int i;
|
||
|
int rc;
|
||
|
|
||
|
@@ -1016,13 +1017,18 @@ build_program_table(int fd, struct job_d
|
||
|
component_header_ipl;
|
||
|
printf("\n");
|
||
|
}
|
||
|
+ if (job->is_secure != SECURE_BOOT_UNDEFINED)
|
||
|
+ is_secure = job->is_secure;
|
||
|
+ else
|
||
|
+ is_secure =
|
||
|
+ job->data.menu.entry[i].is_secure;
|
||
|
rc = add_ipl_program(fd,
|
||
|
&job->data.menu.entry[i].data.ipl,
|
||
|
&table[job->data.menu.entry[i].pos],
|
||
|
verbose || job->command_line,
|
||
|
job->add_files, component_header,
|
||
|
info, &job->target,
|
||
|
- job->is_secure);
|
||
|
+ is_secure);
|
||
|
break;
|
||
|
case job_print_usage:
|
||
|
case job_print_version:
|
||
|
--- a/zipl/src/job.c
|
||
|
+++ b/zipl/src/job.c
|
||
|
@@ -119,6 +119,7 @@ get_command_line(int argc, char* argv[],
|
||
|
memset((void *) &cmdline, 0, sizeof(struct command_line));
|
||
|
cmdline.type = section_invalid;
|
||
|
is_keyword = 0;
|
||
|
+ cmdline.is_secure = SECURE_BOOT_UNDEFINED;
|
||
|
/* Process options */
|
||
|
do {
|
||
|
opt = getopt_long(argc, argv, option_string, options, NULL);
|
||
|
@@ -1055,6 +1056,21 @@ check_job_mvdump_data(struct job_mvdump_
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+check_secure_boot(struct job_data *job)
|
||
|
+{
|
||
|
+ switch (job->is_secure) {
|
||
|
+ case SECURE_BOOT_UNDEFINED:
|
||
|
+ case SECURE_BOOT_DISABLED:
|
||
|
+ case SECURE_BOOT_ENABLED:
|
||
|
+ case SECURE_BOOT_AUTO:
|
||
|
+ return 0;
|
||
|
+ default:
|
||
|
+ error_reason("Invalid secure boot setting '%d'",
|
||
|
+ job->is_secure);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+}
|
||
|
|
||
|
static int
|
||
|
check_job_data(struct job_data* job)
|
||
|
@@ -1099,6 +1115,8 @@ check_job_data(struct job_data* job)
|
||
|
case job_mvdump:
|
||
|
rc = check_job_mvdump_data(&job->data.mvdump, job->name);
|
||
|
}
|
||
|
+ if (!rc)
|
||
|
+ rc = check_secure_boot(job);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
@@ -1594,6 +1612,7 @@ get_menu_job(struct scan_token* scan, ch
|
||
|
sizeof(struct job_menu_entry) * job->data.menu.num);
|
||
|
/* Fill in data */
|
||
|
current = 0;
|
||
|
+ job->data.menu.entry->is_secure = SECURE_BOOT_UNDEFINED;
|
||
|
for (i=index+1; (scan[i].id != scan_id_empty) &&
|
||
|
(scan[i].id != scan_id_section_heading) &&
|
||
|
(scan[i].id != scan_id_menu_heading); i++) {
|
||
|
@@ -1625,6 +1644,7 @@ get_menu_job(struct scan_token* scan, ch
|
||
|
if (temp_job == NULL)
|
||
|
return -1;
|
||
|
memset((void *) temp_job, 0, sizeof(struct job_data));
|
||
|
+ temp_job->is_secure = SECURE_BOOT_UNDEFINED;
|
||
|
rc = get_job_from_section_data(data, temp_job,
|
||
|
job->data.menu.entry[current].name);
|
||
|
if (rc) {
|
||
|
@@ -1637,6 +1657,8 @@ get_menu_job(struct scan_token* scan, ch
|
||
|
job->data.menu.entry[current].id = job_ipl;
|
||
|
job->data.menu.entry[current].data.ipl =
|
||
|
temp_job->data.ipl;
|
||
|
+ job->data.menu.entry[current].is_secure =
|
||
|
+ temp_job->is_secure;
|
||
|
memset((void *) &temp_job->data.ipl, 0,
|
||
|
sizeof(struct job_ipl_data));
|
||
|
break;
|
||
|
@@ -1874,6 +1896,7 @@ job_get(int argc, char* argv[], struct j
|
||
|
job->add_files = cmdline.add_files;
|
||
|
job->data.mvdump.force = cmdline.force;
|
||
|
job->dry_run = cmdline.dry_run;
|
||
|
+ job->is_secure = SECURE_BOOT_UNDEFINED;
|
||
|
/* Get job data from user input */
|
||
|
if (cmdline.help) {
|
||
|
job->command_line = 1;
|
||
|
@@ -1892,10 +1915,10 @@ job_get(int argc, char* argv[], struct j
|
||
|
job_free(job);
|
||
|
return rc;
|
||
|
}
|
||
|
- if (cmdline.is_secure)
|
||
|
+ if (cmdline.is_secure != SECURE_BOOT_UNDEFINED)
|
||
|
job->is_secure = cmdline.is_secure;
|
||
|
- else
|
||
|
- job->is_secure = job->is_secure ? : SECURE_BOOT_AUTO;
|
||
|
+ else if (job->id != job_menu && job->is_secure == SECURE_BOOT_UNDEFINED)
|
||
|
+ job->is_secure = SECURE_BOOT_AUTO;
|
||
|
|
||
|
/* Check job data for validity */
|
||
|
rc = check_job_data(job);
|