From 5de785e23bfe26d27f989c72a00dbc7286bf9cd1 Mon Sep 17 00:00:00 2001 From: Carl-Daniel Hailfinger Date: Thu, 27 Mar 2008 23:56:36 +0000 Subject: [PATCH] Alvar Kusma found a bug in util/lar: If you try to add a file to a full LAR archive, the LAR utility will segfault. This is reproduced easily by zerofilling the LAR, then adding anything to it. Looking at the code, the reason is obvious: lar_empty_offset() can return an error code (-1). None of the callers check for an error code, they simply assume the return value is valid. Signed-off-by: Carl-Daniel Hailfinger Acked-by: Peter Stuge git-svn-id: svn://coreboot.org/repository/coreboot-v3@647 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- util/lar/lar.h | 2 ++ util/lar/stream.c | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/util/lar/lar.h b/util/lar/lar.h index 411c74a722..73f8245f40 100644 --- a/util/lar/lar.h +++ b/util/lar/lar.h @@ -58,7 +58,9 @@ #define BOOTBLOCK_NAME_LEN 16 typedef uint64_t u64; +typedef int64_t s64; typedef uint32_t u32; +typedef int32_t s32; typedef uint8_t u8; /* NOTE -- This and the coreboot lar.h may NOT be in sync. Be careful. */ diff --git a/util/lar/stream.c b/util/lar/stream.c index 3bea09914b..b50e49d689 100644 --- a/util/lar/stream.c +++ b/util/lar/stream.c @@ -492,7 +492,7 @@ err: * @param lar the LAR archive structure * @return The offset of the first chunk of empty space */ -static int lar_empty_offset(struct lar *lar) +static s64 lar_empty_offset(struct lar *lar) { u32 offset = 0; struct lar_header *header; @@ -508,10 +508,12 @@ static int lar_empty_offset(struct lar *lar) offset += get_next_offset(header); } - if (offset >= get_bootblock_offset(lar->size)) + if (offset >= get_bootblock_offset(lar->size)) { + err("No empty space found!\n"); return -1; + } - return offset; + return (s64)offset; } /** @@ -825,11 +827,16 @@ int header_len(char *pathname, int *new_pathlen) int maxsize(struct lar *lar, char *name) { int size; - u32 offset; + s64 offset; int bootblock_size; /* Find the beginning of the available space in the LAR */ +#warning We should check all chunks of free space in the LAR. Right now we do not return the maximum size, but the size of the first chunk. offset = lar_empty_offset(lar); + if (offset < 0) { + err("maxsize is negative\n"); + return offset; + } /* Figure out how big our header will be */ size = get_bootblock_offset(lar->size) - offset - header_len(name,NULL) - 1; @@ -878,7 +885,7 @@ int lar_add_entry(struct lar *lar, char *pathname, void *data, int ret, hlen; int pathlen; u32 *walk, csum; - u32 offset; + s64 offset; /* Find the beginning of the available space in the LAR */ offset = lar_empty_offset(lar); @@ -886,7 +893,8 @@ int lar_add_entry(struct lar *lar, char *pathname, void *data, /* Figure out how big our header will be */ hlen = header_len(pathname, &pathlen); - if (offset + hlen + complen >= get_bootblock_offset(lar->size)) { + if ((offset < 0) || + (offset + hlen + complen >= get_bootblock_offset(lar->size))) { err("Not enough room in the LAR to add the file.\n"); return -1; }