13 #include <metadata_hash.h>
22 #if ENV_STAGE_HAS_DATA_SECTION
31 if (_preram_cbfs_cache != _postram_cbfs_cache)
33 CONFIG_CBFS_CACHE_ALIGN);
48 name, mdata, &data_offset);
50 struct vb2_hash *metadata_hash =
NULL;
51 if (
CONFIG(TOCTOU_SAFETY)) {
55 die(
"Cannot access CBFS TOCTOU-safely in " ENV_STRING " before CBMEM init!\n");
60 die(
"TODO: set metadata_hash to RW metadata hash here.\n");
149 const union cbfs_mdata *mdata,
bool skip_verification)
152 if (!
CONFIG(CBFS_VERIFICATION) && !
CONFIG(TPM_MEASURED_BOOT))
155 const struct vb2_hash *hash =
NULL;
157 if (
CONFIG(CBFS_VERIFICATION) && !skip_verification) {
163 if (vb2_hash_verify(
buffer, size, hash) != VB2_SUCCESS) {
170 struct vb2_hash calculated_hash;
175 hash = &calculated_hash;
179 ERROR(
"failed to measure '%s' into TCPA log\n", mdata->
h.
filename);
187 size_t buffer_size,
uint32_t compression,
188 const union cbfs_mdata *mdata,
bool skip_verification)
194 DEBUG(
"Decompressing %zu bytes from '%s' to %p with algo %d\n",
197 switch (compression) {
199 if (buffer_size < in_size)
263 size_t size =
sizeof(*context) + additional;
292 ERROR(
"%s(name='%s') readat failed\n", __func__, context->
name);
304 bool force_ro =
false;
307 if (!
CONFIG(CBFS_PRELOAD))
314 DEBUG(
"%s(name='%s')\n", __func__,
name);
323 ERROR(
"%s(name='%s') failed to allocate preload context\n", __func__,
name);
329 ERROR(
"%s(name='%s') failed to allocate %zu bytes for preload buffer\n",
330 __func__,
name, size);
342 ERROR(
"%s(name='%s') failed to start preload thread\n", __func__,
name);
375 ERROR(
"%s(name='%s') Preload thread failed: %u\n", __func__,
name, err);
381 ERROR(
"%s(name='%s') chaining failed\n", __func__,
name);
389 DEBUG(
"%s(name='%s') preload successful\n", __func__,
name);
399 bool skip_verification)
417 loc = allocator(
arg, size, mdata);
431 ERROR(
"Cannot map compressed file %s without cbfs_cache\n", mdata->
h.
filename);
453 bool preload_successful =
false;
456 DEBUG(
"%s(name='%s', alloc=%p(%p), force_ro=%s, type=%d)\n", __func__,
name, allocator,
457 arg, force_ro ?
"true" :
"false",
type ? *
type : -1);
466 else if (*
type != real_type) {
467 ERROR(
"'%s' type mismatch (is %u, expected %u)\n",
475 preload_successful =
true;
481 if (preload_successful)
494 DEBUG(
"%s(area='%s', name='%s', alloc=%p(%p))\n", __func__, area,
name, allocator,
arg);
500 ERROR(
"'%s' not found in '%s'\n",
name, area);
507 return do_alloc(&mdata, &file_rdev, allocator,
arg, size_out,
true);
555 !
CONFIG(NO_XIP_EARLY_STAGES) &&
CONFIG(BOOT_DEVICE_MEMORY_MAPPED)) {
575 compression, &mdata,
false);
596 const struct cbmem_entry *entry;
603 CONFIG_CBFS_MCACHE_RW_PERCENTAGE / 100;
606 cbd->
mcache = _cbfs_mcache;
616 struct vb2_hash *mdata_hash)
623 if (!
CONFIG(CBFS_VERIFICATION) || !mdata_hash)
660 die(
"Cannot locate primary CBFS");
665 die(
"RO CBFS metadata hash verification failure");
667 die(
"RO mcache overflow breaks TOCTOU safety!\n");
669 die(
"RO CBFS initialization error: %d", err);
675 #if !CONFIG(NO_CBFS_MCACHE)
682 void *cbmem_mcache =
cbmem_add(cbmem_id, real_size);
684 printk(
BIOS_ERR,
"Cannot allocate CBMEM mcache %#x (%#zx bytes)!\n",
685 cbmem_id, real_size);
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dstpp, int c, size_t len)
#define assert(statement)
cb_err
coreboot error codes
@ CB_ERR
Generic error code.
@ CB_ERR_ARG
Invalid argument.
@ CB_CBFS_CACHE_FULL
Metadata cache overflowed.
@ CB_SUCCESS
Call completed successfully.
@ CB_CBFS_NOT_FOUND
File not found in directory.
@ CB_CBFS_HASH_MISMATCH
Master hash validation failed.
void cbfs_unmap(void *mapping)
struct mem_pool cbfs_cache
static bool fsps_env(void)
static void * do_alloc(union cbfs_mdata *mdata, struct region_device *rdev, cbfs_allocator_t allocator, void *arg, size_t *size_out, bool skip_verification)
static struct cbfs_preload_context * find_cbfs_preload_context(const char *name)
void cbfs_boot_device_find_mcache(struct cbfs_boot_device *cbd, uint32_t id)
static struct list_node cbfs_preload_context_list
static enum cb_err cbfs_preload_thread_entry(void *arg)
void * _cbfs_default_allocator(void *arg, size_t size, const union cbfs_mdata *unused)
enum cb_err cbfs_init_boot_device(const struct cbfs_boot_device *cbd, struct vb2_hash *mdata_hash)
static size_t cbfs_load_and_decompress(const struct region_device *rdev, void *buffer, size_t buffer_size, uint32_t compression, const union cbfs_mdata *mdata, bool skip_verification)
static void append_cbfs_preload_context(struct cbfs_preload_context *context)
static struct cbfs_preload_context * alloc_cbfs_preload_context(size_t additional)
void * _cbfs_cbmem_allocator(void *arg, size_t size, const union cbfs_mdata *unused)
void * _cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out, bool force_ro, enum cbfs_type *type)
static bool cbfs_lz4_enabled(void)
static void mcache_to_cbmem(const struct cbfs_boot_device *cbd, u32 cbmem_id)
ROMSTAGE_CBMEM_INIT_HOOK(switch_to_postram_cache)
static void free_cbfs_preload_context(struct cbfs_preload_context *context)
static bool fspm_env(void)
static void cbfs_mcache_migrate(int unused)
static bool cbfs_file_hash_mismatch(const void *buffer, size_t size, const union cbfs_mdata *mdata, bool skip_verification)
static enum cb_err get_preload_rdev(struct region_device *rdev, const char *name)
const struct cbfs_boot_device * cbfs_get_boot_device(bool force_ro)
static bool cbfs_lzma_enabled(void)
void cbfs_preload(const char *name)
void * _cbfs_unverified_area_alloc(const char *area, const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out)
enum cb_err _cbfs_boot_lookup(const char *name, bool force_ro, union cbfs_mdata *mdata, struct region_device *rdev)
static void switch_to_postram_cache(int unused)
enum cb_err cbfs_prog_stage_load(struct prog *pstage)
void *(* cbfs_allocator_t)(void *arg, size_t size, const union cbfs_mdata *mdata)
enum cb_err cbfs_mcache_build(cbfs_dev_t dev, void *mcache, size_t size, struct vb2_hash *metadata_hash)
enum cb_err cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name, union cbfs_mdata *mdata_out, size_t *data_offset_out)
size_t cbfs_mcache_real_size(const void *mcache, size_t mcache_size)
const struct vb2_hash * cbfs_file_hash(const union cbfs_mdata *mdata)
enum cb_err cbfs_walk(cbfs_dev_t dev, enum cb_err(*walker)(cbfs_dev_t dev, size_t offset, const union cbfs_mdata *mdata, size_t already_read, void *arg), void *arg, struct vb2_hash *metadata_hash, enum cbfs_walk_flags flags)
enum cb_err cbfs_lookup(cbfs_dev_t dev, const char *name, union cbfs_mdata *mdata_out, size_t *data_offset_out, struct vb2_hash *metadata_hash)
const void * cbfs_find_attr(const union cbfs_mdata *mdata, uint32_t attr_tag, size_t size_check)
#define CBFS_MCACHE_ALIGNMENT
@ CBFS_FILE_ATTR_TAG_COMPRESSION
@ CBFS_FILE_ATTR_TAG_STAGEHEADER
static int cbmem_possibly_online(void)
void * cbmem_entry_start(const struct cbmem_entry *entry)
const struct cbmem_entry * cbmem_entry_find(u32 id)
void * cbmem_add(u32 id, u64 size)
u64 cbmem_entry_size(const struct cbmem_entry *entry)
#define CBMEM_ID_CBFS_RO_MCACHE
#define CBMEM_ID_CBFS_RW_MCACHE
#define printk(level,...)
size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn)
void __noreturn die(const char *fmt,...)
uint32_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2_hash *hash)
Extend a measurement hash taken for a CBFS file into the appropriate PCR.
static struct region_device rdev
int fmap_locate_area_as_rdev(const char *name, struct region_device *area)
static uint64_t be64toh(uint64_t big_endian_64bits)
static uint32_t be32toh(uint32_t big_endian_32bits)
#define REGION_SIZE(name)
void timestamp_add_now(enum timestamp_id id)
size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn)
void list_append(struct list_node *node, struct list_node *head)
#define list_for_each(ptr, head, member)
void list_remove(struct list_node *node)
#define BIOS_INFO
BIOS_INFO - Expected events.
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
#define MEM_POOL_INIT(buf_, size_, alignment_)
void * mem_pool_alloc(struct mem_pool *mp, size_t sz)
void mem_pool_free(struct mem_pool *mp, void *alloc)
static void mem_pool_init(struct mem_pool *mp, void *buf, size_t sz, size_t alignment)
void prog_segment_loaded(uintptr_t start, size_t size, int flags)
static void prog_set_entry(struct prog *prog, void *e, void *arg)
static const char * prog_name(const struct prog *prog)
static void * prog_start(const struct prog *prog)
int prog_locate_hook(struct prog *prog)
static size_t prog_size(const struct prog *prog)
static void prog_set_area(struct prog *prog, void *start, size_t size)
u8 buffer[C2P_BUFFER_MAXSIZE]
int rdev_munmap(const struct region_device *rd, void *mapping)
static size_t region_device_sz(const struct region_device *rdev)
int rdev_chain_mem(struct region_device *child, const void *base, size_t size)
static void * rdev_mmap_full(const struct region_device *rd)
int rdev_chain(struct region_device *child, const struct region_device *parent, size_t offset, size_t size)
ssize_t rdev_readat(const struct region_device *rd, void *b, size_t offset, size_t size)
static ssize_t rdev_read_full(const struct region_device *rd, void *b)
#define ENV_STAGE_SUPPORTS_COOP
#define ENV_INITIAL_STAGE
#define ENV_ROMSTAGE_OR_BEFORE
#define ENV_SEPARATE_VERSTAGE
int strcmp(const char *s1, const char *s2)
char * strcpy(char *dst, const char *src)
size_t strlen(const char *src)
struct region_device rdev
uint32_t decompressed_size
struct region_device rdev
struct thread_handle handle
struct list_node list_node
int thread_run(struct thread_handle *handle, enum cb_err(*func)(void *), void *arg)
enum cb_err thread_join(struct thread_handle *handle)
const struct cbfs_boot_device * vboot_get_cbfs_boot_device(void)