diff --git a/include/mdbtools.h b/include/mdbtools.h index c553c95..30381b3 100644 --- a/include/mdbtools.h +++ b/include/mdbtools.h @@ -573,7 +573,7 @@ extern int mdb_update_row(MdbTableDef *table); extern void *mdb_new_data_pg(MdbCatalogEntry *entry); /* map.c */ -extern guint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size); +extern gint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size); extern gint32 mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg); /* props.c */ diff --git a/src/libmdb/data.c b/src/libmdb/data.c index 3fb76d9..bf0a6f6 100644 --- a/src/libmdb/data.c +++ b/src/libmdb/data.c @@ -142,6 +142,7 @@ int mdb_find_row(MdbHandle *mdb, int row, int *start, size_t *len) *len = next_start - (*start & OFFSET_MASK); if ((*start & OFFSET_MASK) >= mdb->fmt->pg_size || + (*start & OFFSET_MASK) > next_start || next_start > mdb->fmt->pg_size) return -1; @@ -527,6 +528,8 @@ mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr) &buf, &row_start, &len)) { return 0; } + if (len < 4) + return 0; mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len); if (col->bind_ptr) diff --git a/src/libmdb/map.c b/src/libmdb/map.c index c11b3b5..5182ffe 100644 --- a/src/libmdb/map.c +++ b/src/libmdb/map.c @@ -68,7 +68,7 @@ mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guin } if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) { fprintf(stderr, "Oops! didn't get a full page at %d\n", map_pg); - exit(1); + return -1; } usage_bitmap = mdb->alt_pg_buf + 4; @@ -97,13 +97,13 @@ mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint fprintf(stderr, "Warning: unrecognized usage map type: %d\n", map[0]); return -1; } -guint32 +gint32 mdb_alloc_page(MdbTableDef *table) { printf("Allocating new page\n"); return 0; } -guint32 +gint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size) { MdbCatalogEntry *entry = table->entry; @@ -119,11 +119,10 @@ mdb_map_find_next_freepage(MdbTableDef *table, int row_size) //printf("looking at page %d\n", pgnum); if (!pgnum) { /* allocate new page */ - pgnum = mdb_alloc_page(table); - return pgnum; + return mdb_alloc_page(table); } else if (pgnum==-1) { fprintf(stderr, "Error: mdb_map_find_next_freepage error while reading maps.\n"); - exit(1); + return -1; } cur_pg = pgnum; diff --git a/src/libmdb/props.c b/src/libmdb/props.c index c1a0901..7532718 100644 --- a/src/libmdb/props.c +++ b/src/libmdb/props.c @@ -117,7 +117,11 @@ mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len) record_len = mdb_get_int16(kkd, pos); dtype = kkd[pos + 3]; elem = mdb_get_int16(kkd, pos + 4); + if (elem < 0 || elem >= names->len) + break; dsize = mdb_get_int16(kkd, pos + 6); + if (dsize < 0 || pos + 8 + dsize > len) + break; value = g_malloc(dsize + 1); strncpy(value, &kkd[pos + 8], dsize); value[dsize] = '\0'; diff --git a/src/libmdb/write.c b/src/libmdb/write.c index c9d82b6..1a6f455 100644 --- a/src/libmdb/write.c +++ b/src/libmdb/write.c @@ -204,7 +204,7 @@ mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields) } bitmask_sz = (row_cols + 7) / 8; - if (bitmask_sz >= row_end) { + if (bitmask_sz + !IS_JET3(mdb) >= row_end) { fprintf(stderr, "warning: Invalid page buffer detected in mdb_crack_row.\n"); return -1; } @@ -227,6 +227,7 @@ mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields) } if (!success) { fprintf(stderr, "warning: Invalid page buffer detected in mdb_crack_row.\n"); + g_free(var_col_offsets); return -1; } } @@ -273,6 +274,11 @@ mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields) fields[i].siz = 0; fields[i].is_null = 1; } + if (fields[i].start + fields[i].siz > row_end + 1) { + fprintf(stderr, "warning: Invalid data location detected in mdb_crack_row.\n"); + g_free(var_col_offsets); + return -1; + } } g_free(var_col_offsets); @@ -586,7 +592,7 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields) mdb_buffer_dump(row_buffer, 0, new_row_size); } pgnum = mdb_map_find_next_freepage(table, new_row_size); - if (!pgnum) { + if (!pgnum || pgnum == -1) { fprintf(stderr, "Unable to allocate new page.\n"); return 0; }