s390/ipl: read IPL report at early boot
Read the IPL Report block provided by secure-boot, add the entries of the certificate list to the system key ring and print the list of components. PR: Adjust to Vasilys bootdata_preserved patch set. Preserve ipl_cert_list for later use in kexec_file. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Philipp Rudo <prudo@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
d29af5b7a8
Коммит
9641b8cc73
|
@ -28,8 +28,9 @@ endif
|
||||||
|
|
||||||
CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
|
CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
|
||||||
|
|
||||||
obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o string.o ebcdic.o
|
obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
|
||||||
obj-y += sclp_early_core.o mem.o ipl_vmparm.o cmdline.o ctype.o
|
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
|
||||||
|
obj-y += ctype.o
|
||||||
obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o
|
obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o
|
||||||
targets := bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
|
targets := bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
|
||||||
subdir- := compressed
|
subdir- := compressed
|
||||||
|
|
|
@ -10,4 +10,6 @@ void parse_boot_command_line(void);
|
||||||
void setup_memory_end(void);
|
void setup_memory_end(void);
|
||||||
void print_missing_facilities(void);
|
void print_missing_facilities(void);
|
||||||
|
|
||||||
|
unsigned long read_ipl_report(unsigned long safe_offset);
|
||||||
|
|
||||||
#endif /* BOOT_BOOT_H */
|
#endif /* BOOT_BOOT_H */
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <asm/ebcdic.h>
|
||||||
|
#include <asm/sclp.h>
|
||||||
|
#include <asm/sections.h>
|
||||||
|
#include <asm/boot_data.h>
|
||||||
|
#include <uapi/asm/ipl.h>
|
||||||
|
#include "boot.h"
|
||||||
|
|
||||||
|
int __bootdata_preserved(ipl_secure_flag);
|
||||||
|
|
||||||
|
unsigned long __bootdata_preserved(ipl_cert_list_addr);
|
||||||
|
unsigned long __bootdata_preserved(ipl_cert_list_size);
|
||||||
|
|
||||||
|
unsigned long __bootdata(early_ipl_comp_list_addr);
|
||||||
|
unsigned long __bootdata(early_ipl_comp_list_size);
|
||||||
|
|
||||||
|
#define for_each_rb_entry(entry, rb) \
|
||||||
|
for (entry = rb->entries; \
|
||||||
|
(void *) entry + sizeof(*entry) <= (void *) rb + rb->len; \
|
||||||
|
entry++)
|
||||||
|
|
||||||
|
static inline bool intersects(unsigned long addr0, unsigned long size0,
|
||||||
|
unsigned long addr1, unsigned long size1)
|
||||||
|
{
|
||||||
|
return addr0 + size0 > addr1 && addr1 + size1 > addr0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long find_bootdata_space(struct ipl_rb_components *comps,
|
||||||
|
struct ipl_rb_certificates *certs,
|
||||||
|
unsigned long safe_addr)
|
||||||
|
{
|
||||||
|
struct ipl_rb_certificate_entry *cert;
|
||||||
|
struct ipl_rb_component_entry *comp;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the length for the IPL report boot data
|
||||||
|
*/
|
||||||
|
early_ipl_comp_list_size = 0;
|
||||||
|
for_each_rb_entry(comp, comps)
|
||||||
|
early_ipl_comp_list_size += sizeof(*comp);
|
||||||
|
ipl_cert_list_size = 0;
|
||||||
|
for_each_rb_entry(cert, certs)
|
||||||
|
ipl_cert_list_size += sizeof(unsigned int) + cert->len;
|
||||||
|
size = ipl_cert_list_size + early_ipl_comp_list_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start from safe_addr to find a free memory area large
|
||||||
|
* enough for the IPL report boot data. This area is used
|
||||||
|
* for ipl_cert_list_addr/ipl_cert_list_size and
|
||||||
|
* early_ipl_comp_list_addr/early_ipl_comp_list_size. It must
|
||||||
|
* not overlap with any component or any certificate.
|
||||||
|
*/
|
||||||
|
repeat:
|
||||||
|
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE &&
|
||||||
|
intersects(INITRD_START, INITRD_SIZE, safe_addr, size))
|
||||||
|
safe_addr = INITRD_START + INITRD_SIZE;
|
||||||
|
for_each_rb_entry(comp, comps)
|
||||||
|
if (intersects(safe_addr, size, comp->addr, comp->len)) {
|
||||||
|
safe_addr = comp->addr + comp->len;
|
||||||
|
goto repeat;
|
||||||
|
}
|
||||||
|
for_each_rb_entry(cert, certs)
|
||||||
|
if (intersects(safe_addr, size, cert->addr, cert->len)) {
|
||||||
|
safe_addr = cert->addr + cert->len;
|
||||||
|
goto repeat;
|
||||||
|
}
|
||||||
|
early_ipl_comp_list_addr = safe_addr;
|
||||||
|
ipl_cert_list_addr = safe_addr + early_ipl_comp_list_size;
|
||||||
|
|
||||||
|
return safe_addr + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_components_bootdata(struct ipl_rb_components *comps)
|
||||||
|
{
|
||||||
|
struct ipl_rb_component_entry *comp, *ptr;
|
||||||
|
|
||||||
|
ptr = (struct ipl_rb_component_entry *) early_ipl_comp_list_addr;
|
||||||
|
for_each_rb_entry(comp, comps)
|
||||||
|
memcpy(ptr++, comp, sizeof(*ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_certificates_bootdata(struct ipl_rb_certificates *certs)
|
||||||
|
{
|
||||||
|
struct ipl_rb_certificate_entry *cert;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
ptr = (void *) ipl_cert_list_addr;
|
||||||
|
for_each_rb_entry(cert, certs) {
|
||||||
|
*(unsigned int *) ptr = cert->len;
|
||||||
|
ptr += sizeof(unsigned int);
|
||||||
|
memcpy(ptr, (void *) cert->addr, cert->len);
|
||||||
|
ptr += cert->len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long read_ipl_report(unsigned long safe_addr)
|
||||||
|
{
|
||||||
|
struct ipl_rb_certificates *certs;
|
||||||
|
struct ipl_rb_components *comps;
|
||||||
|
struct ipl_pl_hdr *pl_hdr;
|
||||||
|
struct ipl_rl_hdr *rl_hdr;
|
||||||
|
struct ipl_rb_hdr *rb_hdr;
|
||||||
|
unsigned long tmp;
|
||||||
|
void *rl_end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if there is a IPL report by looking at the copy
|
||||||
|
* of the IPL parameter information block.
|
||||||
|
*/
|
||||||
|
if (!ipl_block_valid ||
|
||||||
|
!(ipl_block.hdr.flags & IPL_PL_FLAG_IPLSR))
|
||||||
|
return safe_addr;
|
||||||
|
ipl_secure_flag = !!(ipl_block.hdr.flags & IPL_PL_FLAG_SIPL);
|
||||||
|
/*
|
||||||
|
* There is an IPL report, to find it load the pointer to the
|
||||||
|
* IPL parameter information block from lowcore and skip past
|
||||||
|
* the IPL parameter list, then align the address to a double
|
||||||
|
* word boundary.
|
||||||
|
*/
|
||||||
|
tmp = (unsigned long) S390_lowcore.ipl_parmblock_ptr;
|
||||||
|
pl_hdr = (struct ipl_pl_hdr *) tmp;
|
||||||
|
tmp = (tmp + pl_hdr->len + 7) & -8UL;
|
||||||
|
rl_hdr = (struct ipl_rl_hdr *) tmp;
|
||||||
|
/* Walk through the IPL report blocks in the IPL Report list */
|
||||||
|
certs = NULL;
|
||||||
|
comps = NULL;
|
||||||
|
rl_end = (void *) rl_hdr + rl_hdr->len;
|
||||||
|
rb_hdr = (void *) rl_hdr + sizeof(*rl_hdr);
|
||||||
|
while ((void *) rb_hdr + sizeof(*rb_hdr) < rl_end &&
|
||||||
|
(void *) rb_hdr + rb_hdr->len <= rl_end) {
|
||||||
|
|
||||||
|
switch (rb_hdr->rbt) {
|
||||||
|
case IPL_RBT_CERTIFICATES:
|
||||||
|
certs = (struct ipl_rb_certificates *) rb_hdr;
|
||||||
|
break;
|
||||||
|
case IPL_RBT_COMPONENTS:
|
||||||
|
comps = (struct ipl_rb_components *) rb_hdr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_hdr = (void *) rb_hdr + rb_hdr->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With either the component list or the certificate list
|
||||||
|
* missing the kernel will stay ignorant of secure IPL.
|
||||||
|
*/
|
||||||
|
if (!comps || !certs)
|
||||||
|
return safe_addr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy component and certificate list to a safe area
|
||||||
|
* where the decompressed kernel can find them.
|
||||||
|
*/
|
||||||
|
safe_addr = find_bootdata_space(comps, certs, safe_addr);
|
||||||
|
copy_components_bootdata(comps);
|
||||||
|
copy_certificates_bootdata(certs);
|
||||||
|
|
||||||
|
return safe_addr;
|
||||||
|
}
|
|
@ -25,19 +25,16 @@ unsigned long mem_safe_offset(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void rescue_initrd(void)
|
static void rescue_initrd(unsigned long addr)
|
||||||
{
|
{
|
||||||
unsigned long min_initrd_addr;
|
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
|
if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
|
||||||
return;
|
return;
|
||||||
if (!INITRD_START || !INITRD_SIZE)
|
if (!INITRD_START || !INITRD_SIZE)
|
||||||
return;
|
return;
|
||||||
min_initrd_addr = mem_safe_offset();
|
if (addr <= INITRD_START)
|
||||||
if (min_initrd_addr <= INITRD_START)
|
|
||||||
return;
|
return;
|
||||||
memmove((void *)min_initrd_addr, (void *)INITRD_START, INITRD_SIZE);
|
memmove((void *)addr, (void *)INITRD_START, INITRD_SIZE);
|
||||||
INITRD_START = min_initrd_addr;
|
INITRD_START = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_bootdata(void)
|
static void copy_bootdata(void)
|
||||||
|
@ -52,12 +49,15 @@ static void copy_bootdata(void)
|
||||||
|
|
||||||
void startup_kernel(void)
|
void startup_kernel(void)
|
||||||
{
|
{
|
||||||
|
unsigned long safe_addr;
|
||||||
void *img;
|
void *img;
|
||||||
|
|
||||||
uv_query_info();
|
|
||||||
rescue_initrd();
|
|
||||||
sclp_early_read_info();
|
|
||||||
store_ipl_parmblock();
|
store_ipl_parmblock();
|
||||||
|
safe_addr = mem_safe_offset();
|
||||||
|
safe_addr = read_ipl_report(safe_addr);
|
||||||
|
uv_query_info();
|
||||||
|
rescue_initrd(safe_addr);
|
||||||
|
sclp_early_read_info();
|
||||||
setup_boot_command_line();
|
setup_boot_command_line();
|
||||||
parse_boot_command_line();
|
parse_boot_command_line();
|
||||||
setup_memory_end();
|
setup_memory_end();
|
||||||
|
|
|
@ -7,5 +7,12 @@
|
||||||
extern char early_command_line[COMMAND_LINE_SIZE];
|
extern char early_command_line[COMMAND_LINE_SIZE];
|
||||||
extern struct ipl_parameter_block ipl_block;
|
extern struct ipl_parameter_block ipl_block;
|
||||||
extern int ipl_block_valid;
|
extern int ipl_block_valid;
|
||||||
|
extern int ipl_secure_flag;
|
||||||
|
|
||||||
|
extern unsigned long ipl_cert_list_addr;
|
||||||
|
extern unsigned long ipl_cert_list_size;
|
||||||
|
|
||||||
|
extern unsigned long early_ipl_comp_list_addr;
|
||||||
|
extern unsigned long early_ipl_comp_list_size;
|
||||||
|
|
||||||
#endif /* _ASM_S390_BOOT_DATA_H */
|
#endif /* _ASM_S390_BOOT_DATA_H */
|
||||||
|
|
|
@ -122,6 +122,13 @@ static char *dump_type_str(enum dump_type type)
|
||||||
|
|
||||||
int __bootdata_preserved(ipl_block_valid);
|
int __bootdata_preserved(ipl_block_valid);
|
||||||
struct ipl_parameter_block __bootdata_preserved(ipl_block);
|
struct ipl_parameter_block __bootdata_preserved(ipl_block);
|
||||||
|
int __bootdata_preserved(ipl_secure_flag);
|
||||||
|
|
||||||
|
unsigned long __bootdata_preserved(ipl_cert_list_addr);
|
||||||
|
unsigned long __bootdata_preserved(ipl_cert_list_size);
|
||||||
|
|
||||||
|
unsigned long __bootdata(early_ipl_comp_list_addr);
|
||||||
|
unsigned long __bootdata(early_ipl_comp_list_size);
|
||||||
|
|
||||||
static int reipl_capabilities = IPL_TYPE_UNKNOWN;
|
static int reipl_capabilities = IPL_TYPE_UNKNOWN;
|
||||||
|
|
||||||
|
@ -267,6 +274,15 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
|
|
||||||
static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
|
static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
|
||||||
|
|
||||||
|
static ssize_t ipl_secure_show(struct kobject *kobj,
|
||||||
|
struct kobj_attribute *attr, char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page, "%i\n", !!ipl_secure_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct kobj_attribute sys_ipl_secure_attr =
|
||||||
|
__ATTR(secure, 0444, ipl_secure_show, NULL);
|
||||||
|
|
||||||
static ssize_t ipl_vm_parm_show(struct kobject *kobj,
|
static ssize_t ipl_vm_parm_show(struct kobject *kobj,
|
||||||
struct kobj_attribute *attr, char *page)
|
struct kobj_attribute *attr, char *page)
|
||||||
{
|
{
|
||||||
|
@ -362,6 +378,7 @@ static struct attribute *ipl_fcp_attrs[] = {
|
||||||
&sys_ipl_fcp_bootprog_attr.attr,
|
&sys_ipl_fcp_bootprog_attr.attr,
|
||||||
&sys_ipl_fcp_br_lba_attr.attr,
|
&sys_ipl_fcp_br_lba_attr.attr,
|
||||||
&sys_ipl_ccw_loadparm_attr.attr,
|
&sys_ipl_ccw_loadparm_attr.attr,
|
||||||
|
&sys_ipl_secure_attr.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -377,6 +394,7 @@ static struct attribute *ipl_ccw_attrs_vm[] = {
|
||||||
&sys_ipl_device_attr.attr,
|
&sys_ipl_device_attr.attr,
|
||||||
&sys_ipl_ccw_loadparm_attr.attr,
|
&sys_ipl_ccw_loadparm_attr.attr,
|
||||||
&sys_ipl_vm_parm_attr.attr,
|
&sys_ipl_vm_parm_attr.attr,
|
||||||
|
&sys_ipl_secure_attr.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -384,6 +402,7 @@ static struct attribute *ipl_ccw_attrs_lpar[] = {
|
||||||
&sys_ipl_type_attr.attr,
|
&sys_ipl_type_attr.attr,
|
||||||
&sys_ipl_device_attr.attr,
|
&sys_ipl_device_attr.attr,
|
||||||
&sys_ipl_ccw_loadparm_attr.attr,
|
&sys_ipl_ccw_loadparm_attr.attr,
|
||||||
|
&sys_ipl_secure_attr.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/start_kernel.h>
|
#include <linux/start_kernel.h>
|
||||||
|
|
||||||
|
#include <asm/boot_data.h>
|
||||||
#include <asm/ipl.h>
|
#include <asm/ipl.h>
|
||||||
#include <asm/facility.h>
|
#include <asm/facility.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
@ -741,6 +742,15 @@ static void __init reserve_initrd(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserve the memory area used to pass the certificate lists
|
||||||
|
*/
|
||||||
|
static void __init reserve_certificate_list(void)
|
||||||
|
{
|
||||||
|
if (ipl_cert_list_addr)
|
||||||
|
memblock_reserve(ipl_cert_list_addr, ipl_cert_list_size);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init reserve_mem_detect_info(void)
|
static void __init reserve_mem_detect_info(void)
|
||||||
{
|
{
|
||||||
unsigned long start, size;
|
unsigned long start, size;
|
||||||
|
@ -1035,6 +1045,38 @@ static void __init setup_control_program_code(void)
|
||||||
asm volatile("diag %0,0,0x318\n" : : "d" (diag318_info.val));
|
asm volatile("diag %0,0,0x318\n" : : "d" (diag318_info.val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the component list from the IPL report
|
||||||
|
*/
|
||||||
|
static void __init log_component_list(void)
|
||||||
|
{
|
||||||
|
struct ipl_rb_component_entry *ptr, *end;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
if (!early_ipl_comp_list_addr)
|
||||||
|
return;
|
||||||
|
if (ipl_block.hdr.flags & IPL_PL_FLAG_IPLSR)
|
||||||
|
pr_info("Linux is running with Secure-IPL enabled\n");
|
||||||
|
else
|
||||||
|
pr_info("Linux is running with Secure-IPL disabled\n");
|
||||||
|
ptr = (void *) early_ipl_comp_list_addr;
|
||||||
|
end = (void *) ptr + early_ipl_comp_list_size;
|
||||||
|
pr_info("The IPL report contains the following components:\n");
|
||||||
|
while (ptr < end) {
|
||||||
|
if (ptr->flags & IPL_RB_COMPONENT_FLAG_SIGNED) {
|
||||||
|
if (ptr->flags & IPL_RB_COMPONENT_FLAG_VERIFIED)
|
||||||
|
str = "signed, verified";
|
||||||
|
else
|
||||||
|
str = "signed, verification failed";
|
||||||
|
} else {
|
||||||
|
str = "not signed";
|
||||||
|
}
|
||||||
|
pr_info("%016llx - %016llx (%s)\n",
|
||||||
|
ptr->addr, ptr->addr + ptr->len, str);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup function called from init/main.c just after the banner
|
* Setup function called from init/main.c just after the banner
|
||||||
* was printed.
|
* was printed.
|
||||||
|
@ -1055,6 +1097,8 @@ void __init setup_arch(char **cmdline_p)
|
||||||
else
|
else
|
||||||
pr_info("Linux is running as a guest in 64-bit mode\n");
|
pr_info("Linux is running as a guest in 64-bit mode\n");
|
||||||
|
|
||||||
|
log_component_list();
|
||||||
|
|
||||||
/* Have one command line that is parsed and saved in /proc/cmdline */
|
/* Have one command line that is parsed and saved in /proc/cmdline */
|
||||||
/* boot_command_line has been already set up in early.c */
|
/* boot_command_line has been already set up in early.c */
|
||||||
*cmdline_p = boot_command_line;
|
*cmdline_p = boot_command_line;
|
||||||
|
@ -1086,6 +1130,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
reserve_oldmem();
|
reserve_oldmem();
|
||||||
reserve_kernel();
|
reserve_kernel();
|
||||||
reserve_initrd();
|
reserve_initrd();
|
||||||
|
reserve_certificate_list();
|
||||||
reserve_mem_detect_info();
|
reserve_mem_detect_info();
|
||||||
memblock_allow_resize();
|
memblock_allow_resize();
|
||||||
|
|
||||||
|
|
|
@ -55,13 +55,22 @@ config INTEGRITY_PLATFORM_KEYRING
|
||||||
bool "Provide keyring for platform/firmware trusted keys"
|
bool "Provide keyring for platform/firmware trusted keys"
|
||||||
depends on INTEGRITY_ASYMMETRIC_KEYS
|
depends on INTEGRITY_ASYMMETRIC_KEYS
|
||||||
depends on SYSTEM_BLACKLIST_KEYRING
|
depends on SYSTEM_BLACKLIST_KEYRING
|
||||||
depends on EFI
|
|
||||||
help
|
help
|
||||||
Provide a separate, distinct keyring for platform trusted keys, which
|
Provide a separate, distinct keyring for platform trusted keys, which
|
||||||
the kernel automatically populates during initialization from values
|
the kernel automatically populates during initialization from values
|
||||||
provided by the platform for verifying the kexec'ed kerned image
|
provided by the platform for verifying the kexec'ed kerned image
|
||||||
and, possibly, the initramfs signature.
|
and, possibly, the initramfs signature.
|
||||||
|
|
||||||
|
config LOAD_UEFI_KEYS
|
||||||
|
depends on INTEGRITY_PLATFORM_KEYRING
|
||||||
|
depends on EFI
|
||||||
|
def_bool y
|
||||||
|
|
||||||
|
config LOAD_IPL_KEYS
|
||||||
|
depends on INTEGRITY_PLATFORM_KEYRING
|
||||||
|
depends on S390
|
||||||
|
def_bool y
|
||||||
|
|
||||||
config INTEGRITY_AUDIT
|
config INTEGRITY_AUDIT
|
||||||
bool "Enables integrity auditing support "
|
bool "Enables integrity auditing support "
|
||||||
depends on AUDIT
|
depends on AUDIT
|
||||||
|
|
|
@ -9,10 +9,10 @@ integrity-y := iint.o
|
||||||
integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
|
integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
|
||||||
integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
|
integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
|
||||||
integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
|
integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
|
||||||
integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \
|
integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o
|
||||||
platform_certs/efi_parser.o \
|
integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
|
||||||
platform_certs/load_uefi.o
|
platform_certs/load_uefi.o
|
||||||
obj-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/load_uefi.o
|
integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o
|
||||||
$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
|
$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
|
||||||
|
|
||||||
subdir-$(CONFIG_IMA) += ima
|
subdir-$(CONFIG_IMA) += ima
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/cred.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/efi.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <keys/asymmetric-type.h>
|
||||||
|
#include <keys/system_keyring.h>
|
||||||
|
#include <asm/boot_data.h>
|
||||||
|
#include "../integrity.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the certs contained in the IPL report created by the machine loader
|
||||||
|
* into the platform trusted keyring.
|
||||||
|
*/
|
||||||
|
static int __init load_ipl_certs(void)
|
||||||
|
{
|
||||||
|
void *ptr, *end;
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
|
if (!ipl_cert_list_addr)
|
||||||
|
return 0;
|
||||||
|
/* Copy the certificates to the system keyring */
|
||||||
|
ptr = (void *) ipl_cert_list_addr;
|
||||||
|
end = ptr + ipl_cert_list_size;
|
||||||
|
while ((void *) ptr < end) {
|
||||||
|
len = *(unsigned int *) ptr;
|
||||||
|
ptr += sizeof(unsigned int);
|
||||||
|
add_to_platform_keyring("IPL:db", ptr, len);
|
||||||
|
ptr += len;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
late_initcall(load_ipl_certs);
|
Загрузка…
Ссылка в новой задаче