cpu/x86/smm: Add helper functions to verify SMM access
* Add a function to check if a region overlaps with SMM. * Add a function to check if a pointer points to SMM. * Document functions in Documentation/security/smm To be used to verify data accesses in SMM. Change-Id: Ia525d2bc685377f50ecf3bdcf337a4c885488213 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Signed-off-by: Christian Walter <christian.walter@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41084 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
c59d9e3917
commit
41fec869fb
|
@ -13,3 +13,7 @@ This section describes documentation about the security architecture of coreboot
|
||||||
- [Intel TXT in general](intel/txt.md)
|
- [Intel TXT in general](intel/txt.md)
|
||||||
- [Intel TXT Initial Boot Block](intel/txt_ibb.md)
|
- [Intel TXT Initial Boot Block](intel/txt_ibb.md)
|
||||||
- [Intel Authenticated Code Modules](intel/acm.md)
|
- [Intel Authenticated Code Modules](intel/acm.md)
|
||||||
|
|
||||||
|
## SMM
|
||||||
|
|
||||||
|
- [System Management Mode](smm.md)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# x86 System Managment Mode
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The code running in System Management Mode (SMM) provides runtime services
|
||||||
|
to applications running in [ring0]. It has a higher privilege level than
|
||||||
|
[ring0] and resides in the SMRAM region which cannot be accessed from [ring0].
|
||||||
|
|
||||||
|
SMM can be entered by issuing System Managment Interrupts (SMIs).
|
||||||
|
|
||||||
|
## Secure data exchange
|
||||||
|
|
||||||
|
In order to not leak SMM internals or accidentally overwrite parts of SMM,
|
||||||
|
[ring0] provided data (pointers, offsets, sizes, ...) must be checked before
|
||||||
|
using them in SMM.
|
||||||
|
|
||||||
|
There exist two methods to verify data:
|
||||||
|
|
||||||
|
```C
|
||||||
|
/* Returns true if the region overlaps with the SMM */
|
||||||
|
bool smm_region_overlaps_handler(struct region *r);
|
||||||
|
```
|
||||||
|
|
||||||
|
```C
|
||||||
|
/* Returns true if the memory pointed to overlaps with SMM reserved memory. */
|
||||||
|
static inline bool smm_points_to_smram(const void *ptr, const size_t len);
|
||||||
|
```
|
||||||
|
|
||||||
|
[ring0]: https://en.wikipedia.org/wiki/Protection_ring
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
#include <commonlib/region.h>
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <cpu/x86/smi_deprecated.h>
|
#include <cpu/x86/smi_deprecated.h>
|
||||||
#include <cpu/amd/amd64_save_state.h>
|
#include <cpu/amd/amd64_save_state.h>
|
||||||
|
@ -119,6 +120,13 @@ static inline void *smm_save_state(uintptr_t base, int arch_offset, int node)
|
||||||
return (void *)base;
|
return (void *)base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool smm_region_overlaps_handler(const struct region *r)
|
||||||
|
{
|
||||||
|
const struct region r_smm = {SMM_BASE, SMM_DEFAULT_SIZE};
|
||||||
|
|
||||||
|
return region_overlap(&r_smm, r);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Interrupt handler for SMI#
|
* @brief Interrupt handler for SMI#
|
||||||
*
|
*
|
||||||
|
@ -129,7 +137,7 @@ void smi_handler(u32 smm_revision)
|
||||||
{
|
{
|
||||||
unsigned int node;
|
unsigned int node;
|
||||||
smm_state_save_area_t state_save;
|
smm_state_save_area_t state_save;
|
||||||
u32 smm_base = 0xa0000; /* ASEG */
|
u32 smm_base = SMM_BASE; /* ASEG */
|
||||||
|
|
||||||
/* Are we ok to execute the handler? */
|
/* Are we ok to execute the handler? */
|
||||||
if (!smi_obtain_lock()) {
|
if (!smi_obtain_lock()) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
#include <commonlib/region.h>
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <rmodule.h>
|
#include <rmodule.h>
|
||||||
|
|
||||||
|
@ -103,6 +104,14 @@ void *smm_get_save_state(int cpu)
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool smm_region_overlaps_handler(const struct region *r)
|
||||||
|
{
|
||||||
|
const struct region r_smm = {smm_runtime->smbase, smm_runtime->smm_size};
|
||||||
|
const struct region r_aseg = {SMM_BASE, SMM_DEFAULT_SIZE};
|
||||||
|
|
||||||
|
return region_overlap(&r_smm, r) || region_overlap(&r_aseg, r);
|
||||||
|
}
|
||||||
|
|
||||||
asmlinkage void smm_handler_start(void *arg)
|
asmlinkage void smm_handler_start(void *arg)
|
||||||
{
|
{
|
||||||
const struct smm_module_params *p;
|
const struct smm_module_params *p;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#define CPU_X86_SMM_H
|
#define CPU_X86_SMM_H
|
||||||
|
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
#include <commonlib/region.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#define SMM_DEFAULT_BASE 0x30000
|
#define SMM_DEFAULT_BASE 0x30000
|
||||||
|
@ -93,6 +94,17 @@ asmlinkage void smm_handler_start(void *params);
|
||||||
* account CPUs which are configured to not save their state to RAM. */
|
* account CPUs which are configured to not save their state to RAM. */
|
||||||
void *smm_get_save_state(int cpu);
|
void *smm_get_save_state(int cpu);
|
||||||
|
|
||||||
|
/* Returns true if the region overlaps with the SMM */
|
||||||
|
bool smm_region_overlaps_handler(const struct region *r);
|
||||||
|
|
||||||
|
/* Returns true if the memory pointed to overlaps with SMM reserved memory. */
|
||||||
|
static inline bool smm_points_to_smram(const void *ptr, const size_t len)
|
||||||
|
{
|
||||||
|
const struct region r = {(uintptr_t)ptr, len};
|
||||||
|
|
||||||
|
return smm_region_overlaps_handler(&r);
|
||||||
|
}
|
||||||
|
|
||||||
/* SMM Module Loading API */
|
/* SMM Module Loading API */
|
||||||
|
|
||||||
/* The smm_loader_params structure provides direction to the SMM loader:
|
/* The smm_loader_params structure provides direction to the SMM loader:
|
||||||
|
|
Loading…
Reference in New Issue