summaryrefslogtreecommitdiff
path: root/storage/myisam
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay.choubey@oracle.com>2011-11-29 17:59:35 +0530
committerNirbhay Choubey <nirbhay.choubey@oracle.com>2011-11-29 17:59:35 +0530
commitc67a91f11afd730ab050e3c5da16411b95c325a7 (patch)
tree370462b6c1d10f330b9628f9b4ea81cfd8f607eb /storage/myisam
parenta00f87bf155fda703ffd314e5d8166583db92d93 (diff)
downloadmariadb-git-c67a91f11afd730ab050e3c5da16411b95c325a7.tar.gz
Bug#11756764 48726: MYSQLD KEEPS CRASHING WITH SIGSEGV
WITH MYISAM_USE_MMAP ENABLED MySQL server can crash due to segmentation fault when started with myisam_use_mmap. The reason behind this being, while making a request to unmap (munmap) the previously mapped memory (mmap), the size passed was 7 bytes larger than the size requested at the time of mapping. This can eventually unmap the adjacent memory mapped block, belonging to some other memory-map pool. Hence the subsequent call to mmap can map a region which was still a valid memory mapped area. Fixed by removing the extra 7-byte margin which was erroneously added to the size, used for unmappping. storage/myisam/mi_close.c: Bug#11756764 48726: MYSQLD KEEPS CRASHING WITH SIGSEGV WITH MYISAM_USE_MMAP ENABLED Added a condition to call _mi_unmap_file() in case of compressed records. mi_munmap_file() is called otherwise. storage/myisam/mi_packrec.c: Bug#11756764 48726: MYSQLD KEEPS CRASHING WITH SIGSEGV WITH MYISAM_USE_MMAP ENABLED mi_dynmap_file() function, after successfully executing mmap, stores the total size in info->s->mapped_length variable. Now, if mi_dynmap_file() is invoked with a size with an extra 7-byte margin (MEMMAP_EXTRA_MARGIN), the margin will eventually also get stored in mapped_length. So, un-mapping function can simply use the value stored in mapped_length in order to unmap the previously mapped region.
Diffstat (limited to 'storage/myisam')
-rw-r--r--storage/myisam/mi_close.c7
-rw-r--r--storage/myisam/mi_packrec.c7
2 files changed, 10 insertions, 4 deletions
diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c
index bb95aff24d7..a6911814608 100644
--- a/storage/myisam/mi_close.c
+++ b/storage/myisam/mi_close.c
@@ -87,7 +87,12 @@ int mi_close(register MI_INFO *info)
}
#ifdef HAVE_MMAP
if (share->file_map)
- _mi_unmap_file(info);
+ {
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ _mi_unmap_file(info);
+ else
+ mi_munmap_file(info);
+ }
#endif
if (share->decode_trees)
{
diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c
index e6ad4c3defc..005f8c65d71 100644
--- a/storage/myisam/mi_packrec.c
+++ b/storage/myisam/mi_packrec.c
@@ -1553,13 +1553,14 @@ my_bool _mi_memmap_file(MI_INFO *info)
void _mi_unmap_file(MI_INFO *info)
{
- VOID(my_munmap((char*) info->s->file_map,
- (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN));
+ DBUG_ASSERT(info->s->options & HA_OPTION_COMPRESS_RECORD);
+
+ VOID(my_munmap((char*) info->s->file_map, (size_t) info->s->mmaped_length));
if (myisam_mmap_size != SIZE_T_MAX)
{
pthread_mutex_lock(&THR_LOCK_myisam_mmap);
- myisam_mmap_used-= info->s->mmaped_length + MEMMAP_EXTRA_MARGIN;
+ myisam_mmap_used-= info->s->mmaped_length;
pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
}
}