summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-01-21 12:50:49 +0100
committerSergei Golubchik <serg@mariadb.org>2018-01-22 11:39:54 +0100
commit36eb0b7a558542689ad654a770c3f1ce8f18dd87 (patch)
treedc89f7dff191c7dc5d103e71cfd94cdf0db7db9a
parentfa331acefd6b5907b06d394ae0ae096749129601 (diff)
downloadmariadb-git-36eb0b7a558542689ad654a770c3f1ce8f18dd87.tar.gz
improve ASAN instrumentation: table->record[0]
instrument table->record[0], table->record[1] and share->default_values. One should not access record image beyond share->reclength, even if table->record[0] has some unused space after it (functions that work with records, might get a copy of the record as an argument, and that copy - not being record[0] - might not have this buffer space at the end). See b80fa4000d6 and 444587d8a3c
-rw-r--r--sql/table.cc8
-rw-r--r--storage/heap/ha_heap.cc10
2 files changed, 15 insertions, 3 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 6795621b719..5d73d7dffd2 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1269,9 +1269,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
extra_rec_buf_length= uint2korr(head+59);
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
share->rec_buff_length= rec_buff_length;
- if (!(record= (uchar *) alloc_root(&share->mem_root,
- rec_buff_length)))
+ if (!(record= (uchar *) alloc_root(&share->mem_root, rec_buff_length)))
goto err; /* purecov: inspected */
+ MEM_NOACCESS(record, rec_buff_length);
+ MEM_UNDEFINED(record, share->reclength);
share->default_values= record;
if (mysql_file_pread(file, record, (size_t) share->reclength,
record_offset, MYF(MY_NABP)))
@@ -2430,6 +2431,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
if (!(record= (uchar*) alloc_root(&outparam->mem_root,
share->rec_buff_length * records)))
goto err; /* purecov: inspected */
+ MEM_NOACCESS(record, share->rec_buff_length * records);
if (records == 0)
{
@@ -2444,6 +2446,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
else
outparam->record[1]= outparam->record[0]; // Safety
}
+ MEM_UNDEFINED(outparam->record[0], share->reclength);
+ MEM_UNDEFINED(outparam->record[1], share->reclength);
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
(uint) ((share->fields+1)*
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 345ebb8419f..259e54bfc59 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -100,7 +100,15 @@ const char **ha_heap::bas_ext() const
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
- set_if_bigger(table->s->reclength, sizeof (uchar*));
+ if (table->s->reclength < sizeof (char*))
+ {
+ MEM_UNDEFINED(table->s->default_values + table->s->reclength,
+ sizeof(char*) - table->s->reclength);
+ table->s->reclength= sizeof(char*);
+ MEM_UNDEFINED(table->record[0], table->s->reclength);
+ MEM_UNDEFINED(table->record[1], table->s->reclength);
+ }
+
internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
{