summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>2010-12-07 12:27:36 +0100
committerLuc Verhaegen <libv@skynet.be>2010-12-07 12:27:36 +0100
commit5c93e5c170982fa45945ef229d37e204850a5a64 (patch)
tree3f47c3a16d07b63ae21ff906863356d535776daf
parente32568e69ef7fa62574b59cad7cf4a5dfaf81228 (diff)
ami_slab: Add error checking.
Check for not exceeding the file size and using all data in the file Also, write doesn't set errno on short writes, only on hard errors. Signed-off-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
-rw-r--r--ami_slab.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/ami_slab.c b/ami_slab.c
index b7c9780..07a6e1d 100644
--- a/ami_slab.c
+++ b/ami_slab.c
@@ -58,14 +58,18 @@ int slabextract(const unsigned char *buffer, int bufferlen)
const struct slabheader *h = (const void *) buffer;
const unsigned char *listpointer;
const unsigned char *datapointer;
- int i, count;
-
+ int i, count, headersize;
+ headersize = le16toh(h->headersize);
count = le16toh(h->entries);
+ if ((headersize < ((count * 8) + 4)) || (bufferlen < headersize)) {
+ fprintf(stderr, "Invalid file header - probably not a SLAB file\n");
+ return 1;
+ }
printf("%d entries\n", count);
/* FIXME: Is the 37 really constant? */
- if (8 * count + 37 < le32toh(h->headersize)) {
+ if (((8 * count) + 37) < headersize) {
listpointer = buffer + 8 * count + 37;
printf("Name Tp ");
} else {
@@ -106,13 +110,23 @@ int slabextract(const unsigned char *buffer, int bufferlen)
has_data ? "yes" : "no");
if (has_data) {
- int outfd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR);
+ int outfd;
+
+ if (datapointer + len > buffer + bufferlen) {
+ fprintf(stderr, "Not enough data. File truncated?\n");
+ return 1;
+ }
+ outfd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
if (outfd != -1) {
- if (write(outfd, datapointer, len) != len)
- fprintf(stderr, "Can't write %s: %s\n", filename,
+ int ret = write(outfd, datapointer, len);
+ if (ret == -1)
+ fprintf(stderr, "Can't write %s: %s\n", filename,
strerror(errno));
- close(outfd);
+ else if (ret < len)
+ fprintf(stderr, "Can't write %s completely: Disk full?\n",
+ filename);
+ close(outfd);
} else
fprintf(stderr, "Can't create output file %s: %s\n", filename,
strerror(errno));
@@ -120,6 +134,10 @@ int slabextract(const unsigned char *buffer, int bufferlen)
}
}
+ if (datapointer != buffer + bufferlen)
+ fprintf(stderr, "Warning: Unexpected %d trailing bytes",
+ (int)(buffer + bufferlen - datapointer));
+
return 0;
}
@@ -155,7 +173,9 @@ int main(int argc, char *argv[])
return 1;
}
- if (InputBufferSize < 0x52) { /* probably incorrect */
+ /* fixed header size - everything else is checked dynamically in
+ slabextract */
+ if (InputBufferSize < 4) {
fprintf(stderr, "Error: \"%s\" is too small to be a SLAB file.\n",
argv[1]);
return 1;