Improved bounds and return value checking (oss-fuzz/29329)

This commit is contained in:
Evan Miller 2021-01-07 19:59:45 -05:00
parent 9b5e591905
commit c31daeb2c4
7 changed files with 59 additions and 17 deletions

View File

@ -661,8 +661,10 @@ mdb_get_relationships(MdbHandle *mdb, const gchar *dbnamespace, const char* tabl
fprintf(stderr, "No MSysRelationships\n"); fprintf(stderr, "No MSysRelationships\n");
return NULL; return NULL;
} }
if (!mdb_read_columns(mdb->relationships_table)) {
mdb_read_columns(mdb->relationships_table); fprintf(stderr, "Unable to read columns of MSysRelationships\n");
return NULL;
}
for (i=0;i<5;i++) { for (i=0;i<5;i++) {
bound[i] = g_malloc0(mdb->bind_size); bound[i] = g_malloc0(mdb->bind_size);
} }

View File

@ -104,7 +104,11 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
goto cleanup; goto cleanup;
} }
mdb_read_columns(table); if (!mdb_read_columns(table)) {
fprintf(stderr, "Unable to read columns of table %s\n", msysobj.object_name);
mdb_free_catalog(mdb);
goto cleanup;
}
if (mdb_bind_column_by_name(table, "Id", obj_id, NULL) == -1 || if (mdb_bind_column_by_name(table, "Id", obj_id, NULL) == -1 ||
mdb_bind_column_by_name(table, "Name", obj_name, NULL) == -1 || mdb_bind_column_by_name(table, "Name", obj_name, NULL) == -1 ||

View File

@ -77,6 +77,8 @@ int mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr, int *len_pt
{ {
MdbColumn *col = NULL; MdbColumn *col = NULL;
if (!table->columns)
return -1;
/* /*
** the column arrary is 0 based, so decrement to get 1 based parameter ** the column arrary is 0 based, so decrement to get 1 based parameter
*/ */
@ -105,6 +107,9 @@ mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr, int
int col_num = -1; int col_num = -1;
MdbColumn *col; MdbColumn *col;
if (!table->columns)
return -1;
for (i=0;i<table->num_cols;i++) { for (i=0;i<table->num_cols;i++) {
col=g_ptr_array_index(table->columns,i); col=g_ptr_array_index(table->columns,i);
if (!g_ascii_strcasecmp(col->name,col_name)) { if (!g_ascii_strcasecmp(col->name,col_name)) {
@ -304,7 +309,7 @@ int mdb_read_row(MdbTableDef *table, unsigned int row)
MdbField *fields; MdbField *fields;
int num_fields; int num_fields;
if (table->num_cols == 0) if (table->num_cols == 0 || !table->columns)
return 0; return 0;
if (mdb_find_row(mdb, row, &row_start, &row_size) == -1 || row_size == 0) { if (mdb_find_row(mdb, row, &row_start, &row_size) == -1 || row_size == 0) {

View File

@ -238,7 +238,11 @@ mdb_read_indices(MdbTableDef *table)
table->num_real_idxs = 0; table->num_real_idxs = 0;
tmpbuf = g_malloc(idx2_sz); tmpbuf = g_malloc(idx2_sz);
for (i=0;i<table->num_idxs;i++) { for (i=0;i<table->num_idxs;i++) {
read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz); if (!read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz)) {
g_free(tmpbuf);
mdb_free_indices(table->indices);
return table->indices = NULL;
}
//fprintf(stderr, "Index defn: "); //fprintf(stderr, "Index defn: ");
//hexdump((unsigned char *)tmpbuf, idx2_sz); //hexdump((unsigned char *)tmpbuf, idx2_sz);
pidx = g_malloc0(sizeof(MdbIndex)); pidx = g_malloc0(sizeof(MdbIndex));
@ -273,7 +277,7 @@ mdb_read_indices(MdbTableDef *table)
name_sz=read_pg_if_16(mdb, &cur_pos); name_sz=read_pg_if_16(mdb, &cur_pos);
} }
tmpbuf = g_malloc(name_sz); tmpbuf = g_malloc(name_sz);
read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz); if (read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz))
mdb_unicode2ascii(mdb, tmpbuf, name_sz, pidx->name, sizeof(pidx->name)); mdb_unicode2ascii(mdb, tmpbuf, name_sz, pidx->name, sizeof(pidx->name));
g_free(tmpbuf); g_free(tmpbuf);
//fprintf(stderr, "index %d type %d name %s\n", pidx->index_num, pidx->index_type, pidx->name); //fprintf(stderr, "index %d type %d name %s\n", pidx->index_num, pidx->index_type, pidx->name);

View File

@ -169,25 +169,35 @@ void *
read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t len) read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t len)
{ {
char* _buf = buf; char* _buf = buf;
char* _end = buf ? buf + len : NULL;
if (*cur_pos < 0)
return NULL;
/* Advance to page which contains the first byte */ /* Advance to page which contains the first byte */
while (*cur_pos >= mdb->fmt->pg_size) { while (*cur_pos >= mdb->fmt->pg_size) {
mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4)); if (!mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4)))
return NULL;
*cur_pos -= (mdb->fmt->pg_size - 8); *cur_pos -= (mdb->fmt->pg_size - 8);
} }
/* Copy pages into buffer */ /* Copy pages into buffer */
while (*cur_pos + len >= (size_t)mdb->fmt->pg_size) { while (*cur_pos + len >= (size_t)mdb->fmt->pg_size) {
int piece_len = mdb->fmt->pg_size - *cur_pos; size_t piece_len = mdb->fmt->pg_size - *cur_pos;
if (_buf) { if (_buf) {
if (_buf + piece_len > _end)
return NULL;
memcpy(_buf, mdb->pg_buf + *cur_pos, piece_len); memcpy(_buf, mdb->pg_buf + *cur_pos, piece_len);
_buf += piece_len; _buf += piece_len;
} }
len -= piece_len; len -= piece_len;
mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4)); if (!mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4)))
return NULL;
*cur_pos = 8; *cur_pos = 8;
} }
/* Copy into buffer from final page */ /* Copy into buffer from final page */
if (len && _buf) { if (len && _buf) {
if (_buf + len > _end)
return NULL;
memcpy(_buf, mdb->pg_buf + *cur_pos, len); memcpy(_buf, mdb->pg_buf + *cur_pos, len);
} }
*cur_pos += len; *cur_pos += len;
@ -246,7 +256,11 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
/* printf("column %d\n", i); /* printf("column %d\n", i);
mdb_buffer_dump(mdb->pg_buf, cur_pos, fmt->tab_col_entry_size); */ mdb_buffer_dump(mdb->pg_buf, cur_pos, fmt->tab_col_entry_size); */
#endif #endif
read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size); if (!read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size)) {
g_free(col);
mdb_free_columns(table->columns);
return table->columns = NULL;
}
pcol = g_malloc0(sizeof(MdbColumn)); pcol = g_malloc0(sizeof(MdbColumn));
pcol->table = table; pcol->table = table;
@ -305,7 +319,7 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
else else
name_sz = read_pg_if_16(mdb, &cur_pos); name_sz = read_pg_if_16(mdb, &cur_pos);
tmp_buf = g_malloc(name_sz); tmp_buf = g_malloc(name_sz);
read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz); if (read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz))
mdb_unicode2ascii(mdb, tmp_buf, name_sz, pcol->name, sizeof(pcol->name)); mdb_unicode2ascii(mdb, tmp_buf, name_sz, pcol->name, sizeof(pcol->name));
g_free(tmp_buf); g_free(tmp_buf);
} }

View File

@ -1344,7 +1344,10 @@ SQLRETURN SQL_API SQLColumns(
LogStatementError(stmt, "Could not read table '%s'", szTableName); LogStatementError(stmt, "Could not read table '%s'", szTableName);
return SQL_ERROR; return SQL_ERROR;
} }
mdb_read_columns(table); if (!mdb_read_columns(table)) {
LogStatementError(stmt, "Could not read columns of table '%s'", szTableName);
return SQL_ERROR;
}
for (j=0; j<table->num_cols; j++) { for (j=0; j<table->num_cols; j++) {
col = g_ptr_array_index(table->columns, j); col = g_ptr_array_index(table->columns, j);

View File

@ -696,7 +696,12 @@ void mdb_sql_describe_table(MdbSQL *sql)
return; return;
} }
mdb_read_columns(table); if (!mdb_read_columns(table)) {
mdb_sql_error(sql, "Could not read columns of table %s", sql_tab->name);
/* the column and table names are no good now */
mdb_sql_reset(sql);
return;
}
ttable = mdb_create_temp_table(mdb, "#describe"); ttable = mdb_create_temp_table(mdb, "#describe");
@ -794,7 +799,12 @@ int found = 0;
mdb_sql_reset(sql); mdb_sql_reset(sql);
return; return;
} }
mdb_read_columns(table); if (!mdb_read_columns(table)) {
mdb_sql_error(sql, "Could not read columns of table %s", sql_tab->name);
/* the column and table names are no good now */
mdb_sql_reset(sql);
return;
}
if (sql->sel_count && !sql->sarg_tree) { if (sql->sel_count && !sql->sarg_tree) {
MdbTableDef *ttable = mdb_create_temp_table(mdb, "#count"); MdbTableDef *ttable = mdb_create_temp_table(mdb, "#count");