diff options
author | Cyril Bur <cyril.bur@au1.ibm.com> | 2018-03-15 16:58:26 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-04-09 03:45:23 -0500 |
commit | 14cefe11f745a1d929263d4c033610b5bc4b4aa8 (patch) | |
tree | 236795c3f8395f6a18004f0b085d011c71e162ea /libflash/libffs.c | |
parent | 9bd1bef2e583bde35912b1a8e013fa2f6d4eb096 (diff) | |
download | blackbird-skiboot-14cefe11f745a1d929263d4c033610b5bc4b4aa8.tar.gz blackbird-skiboot-14cefe11f745a1d929263d4c033610b5bc4b4aa8.zip |
libffs: Fix bad checks for partition overlap
Not all TOCs are written at zero
Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'libflash/libffs.c')
-rw-r--r-- | libflash/libffs.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/libflash/libffs.c b/libflash/libffs.c index 579494ec..221c2b02 100644 --- a/libflash/libffs.c +++ b/libflash/libffs.c @@ -571,7 +571,7 @@ int ffs_next_side(struct ffs_handle *ffs, struct ffs_handle **new_ffs, int ffs_entry_add(struct ffs_hdr *hdr, struct ffs_entry *entry) { const char *smallest_name; - uint32_t smallest_base; + uint32_t smallest_base, toc_base; int i; FL_DBG("LIBFFS: Adding '%s' at 0x%08x..0x%08x\n", @@ -586,6 +586,7 @@ int ffs_entry_add(struct ffs_hdr *hdr, struct ffs_entry *entry) smallest_base = entry->base; smallest_name = entry->name; + toc_base = 0; /* * TODO: This may have assumed entries was sorted */ @@ -609,17 +610,27 @@ int ffs_entry_add(struct ffs_hdr *hdr, struct ffs_entry *entry) if (entry->pid != FFS_PID_TOPLEVEL) return FFS_ERR_BAD_PART_PID; - /* Skip the first partition as it IS the partition table */ - if (ent->base < smallest_base && i > 0) { - smallest_base = ent->base; - smallest_name = ent->name; + /* First partition is the partition table */ + if (i == 0) { + toc_base = ent->base; + } else { + /* + * We're looking for the partition directly + * after the toc to make sure we don't + * overflow onto it. + */ + if (ent->base < smallest_base && ent->base > toc_base) { + smallest_base = ent->base; + smallest_name = ent->name; + } } } - if ((hdr->count + 1) * sizeof(struct __ffs_entry) + - sizeof(struct __ffs_hdr) > smallest_base) { + /* If the smallest base is before the TOC, don't worry */ + if (smallest_base > toc_base && (hdr->count + 1) * sizeof(struct __ffs_entry) + + sizeof(struct __ffs_hdr) + toc_base > smallest_base) { fprintf(stderr, "Adding partition '%s' would cause partition '%s' at " - "0x%08x to overlap with the header\n", entry->name, smallest_name, - smallest_base); + "0x%08x to overlap with the header\n", entry->name, smallest_name, + smallest_base); return FFS_ERR_BAD_PART_BASE; } |