static struct dentry *find_file_in_archive(const struct directory *dir, const char *name) { struct dentry *entry; uintptr_t start; int i; if (!dir) { printf("%s: archive not loaded\n", __func__); return NULL; } /* calculate start of the file content section */ start = get_first_offset(dir); entry = get_first_dentry(dir); for (i = 0; i < dir->count; i++) { if (strncmp(entry[i].name, name, NAME_LENGTH)) continue; /* validate offset & size */ if (entry[i].offset < start || entry[i].offset + entry[i].size > dir->size || entry[i].offset > dir->size || entry[i].size > dir->size) { printf("%s: '%s' has invalid offset or size\n", __func__, name); return NULL; } return &entry[i]; } printf("%s: file '%s' not found\n", __func__, name); return NULL; }
/* * Load archive into RAM */ static VbError_t load_archive(const char *name, struct directory **dest) { struct directory *dir; struct dentry *entry; size_t size; int i; printf("%s: loading %s\n", __func__, name); *dest = NULL; /* load archive from cbfs */ dir = cbfs_get_file_content(ro_cbfs, name, CBFS_TYPE_RAW, &size); if (!dir || !size) { printf("%s: failed to load %s\n", __func__, name); return VBERROR_INVALID_BMPFV; } /* convert endianness of archive header */ dir->count = le32toh(dir->count); dir->size = le32toh(dir->size); /* validate the total size */ if (dir->size != size) { printf("%s: archive size does not match\n", __func__); return VBERROR_INVALID_BMPFV; } /* validate magic field */ if (memcmp(dir->magic, CBAR_MAGIC, sizeof(CBAR_MAGIC))) { printf("%s: invalid archive magic\n", __func__); return VBERROR_INVALID_BMPFV; } /* validate count field */ if (get_first_offset(dir) > dir->size) { printf("%s: invalid count\n", __func__); return VBERROR_INVALID_BMPFV; } /* convert endianness of file headers */ entry = get_first_dentry(dir); for (i = 0; i < dir->count; i++) { entry[i].offset = le32toh(entry[i].offset); entry[i].size = le32toh(entry[i].size); } *dest = dir; return VBERROR_SUCCESS; }
/* * Store files in archive */ static int archive_files(const char **files) { struct dentry *entry; uint32_t offset; int i; entry = get_first_dentry(archive); offset = get_first_offset(archive); for (i = 0; i < archive->count; i++) { if (add_file(files[i], entry, offset)) return -1; offset += entry->size; entry++; } return 0; }