diff options
author | Colin Cross <ccross@android.com> | 2023-05-13 03:16:40 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-05-13 03:16:40 +0000 |
commit | bc33378d825ad6be5750bcbbea62441ace6381fa (patch) | |
tree | 185fb948c28c1c8a633619237f1634c719f5a882 | |
parent | 7b159326c2107d8a23b26a5450fe8ea64988258d (diff) | |
parent | a12e6289988a31254ef6cf714cd679ed4b5061b1 (diff) | |
download | adb-bc33378d825ad6be5750bcbbea62441ace6381fa.tar.gz |
Fix use-after-free in fdevent am: e6e73778ab am: a12e628998
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/adb/+/23122421
Change-Id: Iafd66131d52be5612895ff41d1f9f83c30b775ab
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | fdevent/fdevent.cpp | 10 | ||||
-rw-r--r-- | fdevent/fdevent.h | 3 |
2 files changed, 12 insertions, 1 deletions
diff --git a/fdevent/fdevent.cpp b/fdevent/fdevent.cpp index b0758b81..e20a2953 100644 --- a/fdevent/fdevent.cpp +++ b/fdevent/fdevent.cpp @@ -83,6 +83,7 @@ fdevent* fdevent_context::Create(unique_fd fd, std::variant<fd_func, fd_func2> f LOG(ERROR) << "failed to set non-blocking mode for fd " << fde->fd.get(); } + this->fdevent_set_.insert(fde); this->Register(fde); return fde; } @@ -100,6 +101,8 @@ unique_fd fdevent_context::Destroy(fdevent* fde) { auto erased = this->installed_fdevents_.erase(fd.get()); CHECK_EQ(1UL, erased); + erased = this->fdevent_set_.erase(fde); + CHECK_EQ(1UL, erased); return fd; } @@ -150,7 +153,12 @@ std::optional<std::chrono::milliseconds> fdevent_context::CalculatePollDuration( void fdevent_context::HandleEvents(const std::vector<fdevent_event>& events) { for (const auto& event : events) { - invoke_fde(event.fde, event.events); + // Verify the fde is still installed before invoking it. It could have been unregistered + // and destroyed inside an earlier event handler. + if (this->fdevent_set_.find(event.fde) != this->fdevent_set_.end()) { + invoke_fde(event.fde, event.events); + break; + } } FlushRunQueue(); } diff --git a/fdevent/fdevent.h b/fdevent/fdevent.h index 84d086b6..7f8e1a2c 100644 --- a/fdevent/fdevent.h +++ b/fdevent/fdevent.h @@ -27,6 +27,7 @@ #include <map> #include <mutex> #include <optional> +#include <set> #include <variant> #include <android-base/thread_annotations.h> @@ -131,6 +132,8 @@ struct fdevent_context { uint64_t fdevent_id_ = 0; std::mutex run_queue_mutex_; std::deque<std::function<void()>> run_queue_ GUARDED_BY(run_queue_mutex_); + + std::set<fdevent*> fdevent_set_; }; // Backwards compatibility shims that forward to the global fdevent_context. |