summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/libcbfs/cbfs_core.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/payloads/libpayload/libcbfs/cbfs_core.c b/payloads/libpayload/libcbfs/cbfs_core.c
index e94e1e76ba..30a41f8a72 100644
--- a/payloads/libpayload/libcbfs/cbfs_core.c
+++ b/payloads/libpayload/libcbfs/cbfs_core.c
@@ -212,9 +212,15 @@ struct cbfs_handle *cbfs_get_handle(struct cbfs_media *media, const char *name)
}
// Move to next file.
- offset += ntohl(file.len) + ntohl(file.offset);
- if (offset % CBFS_ALIGNMENT)
- offset += CBFS_ALIGNMENT - (offset % CBFS_ALIGNMENT);
+ uint32_t next_offset = offset + ntohl(file.len) + ntohl(file.offset);
+ if (next_offset % CBFS_ALIGNMENT)
+ next_offset += CBFS_ALIGNMENT - (next_offset % CBFS_ALIGNMENT);
+ // Check that offset is strictly monotonic to prevent infinite loop
+ if (next_offset <= offset) {
+ ERROR("ERROR: corrupted CBFS file header at 0x%x.\n", offset);
+ break;
+ }
+ offset = next_offset;
}
media->close(media);
LOG("WARNING: '%s' not found.\n", name);
@@ -309,7 +315,14 @@ void *cbfs_get_attr(struct cbfs_handle *handle, uint32_t tag)
return NULL;
}
if (ntohl(attr.tag) != tag) {
- offset += ntohl(attr.len);
+ uint32_t next_offset = offset + ntohl(attr.len);
+ // Check that offset is strictly monotonic to prevent infinite loop
+ if (next_offset <= offset) {
+ ERROR("ERROR: corrupted CBFS attribute at 0x%x.\n", offset);
+ m->close(m);
+ return NULL;
+ }
+ offset = next_offset;
continue;
}
ret = m->map(m, offset, ntohl(attr.len));