aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>2017-09-19 14:38:06 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-09-19 04:16:37 -0500
commiteeb4d3226d4eda49ca171d442e49ceccbcaf634e (patch)
tree562fb53d29df9d5c64ae4efd090ce8ca4083e3b8 /core
parent2226def0f65dfcb5b4d6a99c05b62d0691d6821b (diff)
downloadskiboot-eeb4d3226d4eda49ca171d442e49ceccbcaf634e.zip
skiboot-eeb4d3226d4eda49ca171d442e49ceccbcaf634e.tar.gz
skiboot-eeb4d3226d4eda49ca171d442e49ceccbcaf634e.tar.bz2
core/flash: Only expect ELF header for BOOTKERNEL partition flash resource
When loading a flash resource which isn't signed (secure and trusted boot) and which doesn't have a subpartition, we assume it's the BOOTKERNEL since previously this was the only such resource. Thus we also assumed it had an ELF header which we parsed to get the size of the partition rather than trusting the actual_size field in the FFS header. A previous commit (9727fe3 DT: Add ibm,firmware-versions node) added the version resource which isn't signed and also doesn't have a subpartition, thus we expect it to have an ELF header. It doesn't so we print the error message "FLASH: Invalid ELF header part VERSION". It is a fluke that this works currently since we load the secure boot header unconditionally and this happen to be the same size as the version partition. We also don't update the return code on error so happen to return OPAL_SUCCESS. To make this explicitly correct; only check for an ELF header if we are loading the BOOTKERNEL resource, otherwise use the partition size from the FFS header. Also set the return code on error so we don't erroneously return OPAL_SUCCESS. Add a check that the resource will fit in the supplied buffer to prevent buffer overrun. Fixes: 9727fe3 (DT: Add ibm,firmware-versions node) Reported-by: Pridhiviraj Paidipeddi <ppaidipe@linux.vnet.ibm.com> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/flash.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/core/flash.c b/core/flash.c
index 93db8cb..2744496 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -687,6 +687,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid,
if (content_size > bufsz) {
prerror("FLASH: content size > buffer size\n");
+ rc = OPAL_PARAMETER;
goto out_free_ffs;
}
@@ -720,15 +721,28 @@ static int flash_load_resource(enum resource_id id, uint32_t subid,
* Back to the old way of doing things, no STB header.
*/
if (subid == RESOURCE_SUBID_NONE) {
- /*
- * Because actualSize is a lie, we compute the size
- * of the BOOTKERNEL based on what the ELF headers
- * say. Otherwise we end up reading more than we should
- */
- content_size = sizeof_elf_from_hdr(buf);
- if (!content_size) {
- prerror("FLASH: Invalid ELF header part %s\n",
- name);
+ if (id == RESOURCE_ID_KERNEL) {
+ /*
+ * Because actualSize is a lie, we compute the
+ * size of the BOOTKERNEL based on what the ELF
+ * headers say. Otherwise we end up reading more
+ * than we should
+ */
+ content_size = sizeof_elf_from_hdr(buf);
+ if (!content_size) {
+ prerror("FLASH: Invalid ELF header part"
+ " %s\n", name);
+ rc = OPAL_RESOURCE;
+ goto out_free_ffs;
+ }
+ } else {
+ content_size = ffs_part_size;
+ }
+ if (content_size > bufsz) {
+ prerror("FLASH: %s content size %d > "
+ " buffer size %lu\n", name,
+ content_size, bufsz);
+ rc = OPAL_PARAMETER;
goto out_free_ffs;
}
prlog(PR_DEBUG, "FLASH: computed %s size %u\n",