x86/boot: Don't propagate uninitialized boot_params->cc_blob_address
In some cases, bootloaders will leave boot_params->cc_blob_address
uninitialized rather than zeroing it out. This field is only meant to be
set by the boot/compressed kernel in order to pass information to the
uncompressed kernel when SEV-SNP support is enabled.
Therefore, there are no cases where the bootloader-provided values
should be treated as anything other than garbage. Otherwise, the
uncompressed kernel may attempt to access this bogus address, leading to
a crash during early boot.
Normally, sanitize_boot_params() would be used to clear out such fields
but that happens too late: sev_enable() may have already initialized
it to a valid value that should not be zeroed out. Instead, have
sev_enable() zero it out unconditionally beforehand.
Also ensure this happens for !CONFIG_AMD_MEM_ENCRYPT as well by also
including this handling in the sev_enable() stub function.
[ bp: Massage commit message and comments. ]
Fixes: b190a043c4
("x86/sev: Add SEV-SNP feature detection/setup")
Reported-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
Reported-by: watnuss@gmx.de
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: stable@vger.kernel.org
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216387
Link: https://lore.kernel.org/r/20220823160734.89036-1-michael.roth@amd.com
This commit is contained in:
Родитель
ea902bcc19
Коммит
4b1c742407
|
@ -132,7 +132,17 @@ void snp_set_page_private(unsigned long paddr);
|
||||||
void snp_set_page_shared(unsigned long paddr);
|
void snp_set_page_shared(unsigned long paddr);
|
||||||
void sev_prep_identity_maps(unsigned long top_level_pgt);
|
void sev_prep_identity_maps(unsigned long top_level_pgt);
|
||||||
#else
|
#else
|
||||||
static inline void sev_enable(struct boot_params *bp) { }
|
static inline void sev_enable(struct boot_params *bp)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* bp->cc_blob_address should only be set by boot/compressed kernel.
|
||||||
|
* Initialize it to 0 unconditionally (thus here in this stub too) to
|
||||||
|
* ensure that uninitialized values from buggy bootloaders aren't
|
||||||
|
* propagated.
|
||||||
|
*/
|
||||||
|
if (bp)
|
||||||
|
bp->cc_blob_address = 0;
|
||||||
|
}
|
||||||
static inline void sev_es_shutdown_ghcb(void) { }
|
static inline void sev_es_shutdown_ghcb(void) { }
|
||||||
static inline bool sev_es_check_ghcb_fault(unsigned long address)
|
static inline bool sev_es_check_ghcb_fault(unsigned long address)
|
||||||
{
|
{
|
||||||
|
|
|
@ -276,6 +276,14 @@ void sev_enable(struct boot_params *bp)
|
||||||
struct msr m;
|
struct msr m;
|
||||||
bool snp;
|
bool snp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bp->cc_blob_address should only be set by boot/compressed kernel.
|
||||||
|
* Initialize it to 0 to ensure that uninitialized values from
|
||||||
|
* buggy bootloaders aren't propagated.
|
||||||
|
*/
|
||||||
|
if (bp)
|
||||||
|
bp->cc_blob_address = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup/preliminary detection of SNP. This will be sanity-checked
|
* Setup/preliminary detection of SNP. This will be sanity-checked
|
||||||
* against CPUID/MSR values later.
|
* against CPUID/MSR values later.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче