Improve bounds and return-value checking

Fixes a memory leak and a number of buffer overruns
This commit is contained in:
Evan Miller 2020-08-06 15:17:04 -04:00
parent b01c4b8941
commit 2e6e88b96f
5 changed files with 21 additions and 9 deletions

View File

@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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';

View File

@ -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;
}