commit a0d248bea82b178b89e8d1d9015cb002eac261b0
parent c24e9dbe3b9619f8bddb3cc8276135c0ad89c227
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 16 Jul 2018 16:19:44 +0200
Check that the mapped data does not overflow the file size
Diffstat:
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/src/htcp.c b/src/htcp.c
@@ -111,6 +111,7 @@ load_stream(struct htcp* htcp, FILE* stream, const char* stream_name)
{
size_t nz = 0;
size_t map_len = 0;
+ size_t filesz;
off_t offset = 0;
res_T res = RES_OK;
ASSERT(htcp && stream && stream_name);
@@ -182,7 +183,15 @@ load_stream(struct htcp* htcp, FILE* stream, const char* stream_name)
/* Ensure that offset is align on page size */
offset = ALIGN_SIZE(ftell(stream), htcp->pagesize);
+ fseek(stream, 0, SEEK_END);
+ filesz = (size_t)ftell(stream);
+
#define MMAP(Var) { \
+ if((size_t)offset + map_len > filesz) { \
+ log_err(htcp, "%s: coult not load the "STR(Var)" data.\n", stream_name); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
htcp->Var = mmap(NULL, map_len, PROT_READ, MAP_PRIVATE|MAP_POPULATE, \
fileno(stream), offset); \
if(htcp->Var == MAP_FAILED) { \
diff --git a/src/test_htcp_load.c b/src/test_htcp_load.c
@@ -52,30 +52,37 @@ main(int argc, char** argv)
dbl[2] = 3;
CHK(fwrite(dbl, sizeof(dbl[0]), 3, stream) == 3);
+ n = (size_t)(i32[0]*i32[1]*i32[2]*i32[3]);
fseek(stream, ALIGN_SIZE(ftell(stream), pagesize), SEEK_SET); /* padding */
- FOR_EACH(i, 0, i32[0]*i32[1]*i32[2]*i32[3]) { /* RVT */
+ FOR_EACH(i, 0, n) { /* RVT */
dbl[0] = (double)i;
CHK(fwrite(dbl, sizeof(dbl[0]), 1, stream) == 1);
}
fseek(stream, ALIGN_SIZE(ftell(stream), pagesize), SEEK_SET); /* padding */
- FOR_EACH(i, 0, i32[0]*i32[1]*i32[2]*i32[3]) { /* RCT */
+ FOR_EACH(i, 0, n) { /* RCT */
dbl[0] =-(double)i;
CHK(fwrite(dbl, sizeof(dbl[0]), 1, stream) == 1);
}
fseek(stream, ALIGN_SIZE(ftell(stream), pagesize), SEEK_SET); /* padding */
- FOR_EACH(i, 0, i32[0]*i32[1]*i32[2]*i32[3]) { /* PABST */
+ FOR_EACH(i, 0, n) { /* PABST */
dbl[0] =(double)(i*2);
CHK(fwrite(dbl, sizeof(dbl[0]), 1, stream) == 1);
}
fseek(stream, ALIGN_SIZE(ftell(stream), pagesize), SEEK_SET); /* padding */
- FOR_EACH(i, 0, i32[0]*i32[1]*i32[2]*i32[3]) { /* T */
+ FOR_EACH(i, 0, n) { /* T */
dbl[0] =-(double)(i*2);
CHK(fwrite(dbl, sizeof(dbl[0]), 1, stream) == 1);
}
- fseek(stream, ALIGN_SIZE(ftell(stream), pagesize), SEEK_SET); /* padding */
+ if(!IS_ALIGNED(ftell(stream), (size_t)pagesize)) {
+ /* Padding to ensure that the size is aligned on the page size. Note that
+ * one char is written to positioned the EOF indicator */
+ const char byte = 0;
+ fseek(stream, ALIGN_SIZE(ftell(stream), pagesize)-1, SEEK_SET);
+ CHK(fwrite(&byte, 1, 1, stream) == 1);
+ }
rewind(stream);