diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2014-06-08 17:03:34 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2014-06-08 17:03:34 +0900 |
| commit | 570bc24fb98d72d1bce9261fdc29139224ec86ec (patch) | |
| tree | ccf2c67ef8dda9cf91c88fd41941fe0b33ade65c /src/RequestGroupMan.cc | |
| parent | 442e460055fdf045cc70c87fac9f0dd481ad55e2 (diff) | |
Fix use-after-free on exit with multi-file torrent download + DHT
DefaultPieceStorage may be referenced by one of DHT task (e.g.,
DHTPeerLookupTask), after RequestGroup was deleted, and even after
RequestGroupMan was deleted. DefaultPieceStorage has a reference to
MultiDiskAdaptor which calls RequestGroupMan object on destruction.
So when DHT task is destroyed, DefaultPieceStorage is destroyed, which
in turn destroys MultiDiskAdaptor. DHT task is destroyed after
RequestGroupMan was destroyed, MultiDiskAdaptor will use now freed
RequestGroupMan object, this is use-after-free.
Diffstat (limited to 'src/RequestGroupMan.cc')
| -rw-r--r-- | src/RequestGroupMan.cc | 35 |
1 files changed, 4 insertions, 31 deletions
diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc index 92c3b8c6..938f83e5 100644 --- a/src/RequestGroupMan.cc +++ b/src/RequestGroupMan.cc @@ -82,6 +82,7 @@ #include "DiskAdaptor.h" #include "SimpleRandomizer.h" #include "array_fun.h" +#include "OpenedFileCounter.h" #ifdef ENABLE_BITTORRENT # include "bittorrent_helper.h" #endif // ENABLE_BITTORRENT @@ -116,7 +117,8 @@ RequestGroupMan::RequestGroupMan removedLastErrorResult_(error_code::FINISHED), maxDownloadResult_(option->getAsInt(PREF_MAX_DOWNLOAD_RESULT)), wrDiskCache_(nullptr), - numOpenFile_(0), + openedFileCounter_(std::make_shared<OpenedFileCounter> + (this, option->getAsInt(PREF_BT_MAX_OPEN_FILES))), numStoppedTotal_(0) { appendReservedGroup(reservedGroups_, @@ -125,6 +127,7 @@ RequestGroupMan::RequestGroupMan RequestGroupMan::~RequestGroupMan() { + openedFileCounter_->deactivate(); delete wrDiskCache_; } @@ -964,34 +967,4 @@ void RequestGroupMan::initWrDiskCache() } } -void RequestGroupMan::ensureMaxOpenFileLimit(size_t numNewFile) -{ - size_t max = option_->getAsInt(PREF_BT_MAX_OPEN_FILES); - if(numOpenFile_ + numNewFile <= max) { - numOpenFile_ += numNewFile; - return; - } - assert(numNewFile <= max); - size_t numClose = numOpenFile_ + numNewFile - max; - size_t left = numClose; - auto mark = std::begin(requestGroups_); - std::advance(mark, - SimpleRandomizer::getInstance()-> - getRandomNumber(requestGroups_.size())); - for(auto i = mark; i != std::end(requestGroups_) && left > 0; ++i) { - left -= (*i)->getPieceStorage()->getDiskAdaptor()->tryCloseFile(left); - } - for(auto i = std::begin(requestGroups_); i != mark && left > 0; ++i) { - left -= (*i)->getPieceStorage()->getDiskAdaptor()->tryCloseFile(left); - } - assert(left == 0); - numOpenFile_ += numNewFile - numClose; -} - -void RequestGroupMan::reduceNumOfOpenedFile(size_t numCloseFile) -{ - assert(numOpenFile_ >= numCloseFile); - numOpenFile_ -= numCloseFile; -} - } // namespace aria2 |
