summaryrefslogtreecommitdiff
path: root/src/RequestGroupMan.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2014-06-08 17:03:34 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2014-06-08 17:03:34 +0900
commit570bc24fb98d72d1bce9261fdc29139224ec86ec (patch)
treeccf2c67ef8dda9cf91c88fd41941fe0b33ade65c /src/RequestGroupMan.cc
parent442e460055fdf045cc70c87fac9f0dd481ad55e2 (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.cc35
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