diff options
author | Alan Somers <asomers@gmail.com> | 2013-10-15 13:26:13 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-10-15 13:26:15 -0700 |
commit | bd7a7dd6896b175ed15749800ce0ae6a7f0525bd (patch) | |
tree | c9099f8c8cb82bc2e16eab0586b3bf4ee6649144 | |
parent | 26228ed701870a3625a41f798359d4e550b248b8 (diff) | |
download | ceph-bd7a7dd6896b175ed15749800ce0ae6a7f0525bd.tar.gz |
os/FileStore: fix fiemap double-free(s)
If GenericFileStoreBackend::do_fiemap returns anything other than 0, then
fiemap will not be allocated. However,
GenericFileStoreBackend::detect_features will free fiemap regardless,
triggering an assertion in tcmalloc. The attached patch will fix the bug
by only freeing fiemap when necessary.
In my case, do_fiemap returns -ENOSYS because fiemap is not implemented
on FreeBSD. However, this bug could also happen on Linux when do_fiemap
returns -ENOMEM.
Fixes: #6504
Signed-off-by: Alan Somers <asomers@gmail.com>
Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/os/FileStore.cc | 6 | ||||
-rw-r--r-- | src/os/GenericFileStoreBackend.cc | 2 |
2 files changed, 5 insertions, 3 deletions
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 20afde9a0dc..6940dff1405 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -2587,8 +2587,10 @@ int FileStore::fiemap(coll_t cid, const ghobject_t& oid, if (r < 0) goto done; - if (fiemap->fm_mapped_extents == 0) + if (fiemap->fm_mapped_extents == 0) { + free(fiemap); goto done; + } struct fiemap_extent *extent = &fiemap->fm_extents[0]; @@ -2622,6 +2624,7 @@ int FileStore::fiemap(coll_t cid, const ghobject_t& oid, i++; extent++; } + free(fiemap); } done: @@ -2631,7 +2634,6 @@ done: } dout(10) << "fiemap " << cid << "/" << oid << " " << offset << "~" << len << " = " << r << " num_extents=" << exomap.size() << " " << exomap << dendl; - free(fiemap); assert(!m_filestore_fail_eio || r != -EIO); return r; } diff --git a/src/os/GenericFileStoreBackend.cc b/src/os/GenericFileStoreBackend.cc index 81d896a0943..f19ba7d7760 100644 --- a/src/os/GenericFileStoreBackend.cc +++ b/src/os/GenericFileStoreBackend.cc @@ -124,12 +124,12 @@ int GenericFileStoreBackend::detect_features() dout(0) << "detect_features: FIEMAP ioctl is supported and appears to work" << dendl; ioctl_fiemap = true; } + free(fiemap); } if (!m_filestore_fiemap) { dout(0) << "detect_features: FIEMAP ioctl is disabled via 'filestore fiemap' config option" << dendl; ioctl_fiemap = false; } - free(fiemap); ::unlink(fn); TEMP_FAILURE_RETRY(::close(fd)); |