Skip to content

Fix crash when removing connection from the pool - #347

Merged
BewareMyPower merged 1 commit into
apache:mainfrom
BewareMyPower:bewaremypower/fix-crash-cnx-per-broker
Nov 17, 2023
Merged

Fix crash when removing connection from the pool#347
BewareMyPower merged 1 commit into
apache:mainfrom
BewareMyPower:bewaremypower/fix-crash-cnx-per-broker

Conversation

@BewareMyPower

Copy link
Copy Markdown
Contributor

Fixes#346

Motivation

#336 changes the key of the ClientConnection in ConnectionPool, while in ClientConnection::close, it still passes the old key (logical address) to ConnectionPool::remove, which results in the connection could never be removed and destroyed until being deleted as a stale connection.

What's worse, if the key does not exist, the iterator returned by std::map::find will still be dereferenced, which might cause crash in some platforms. See

auto it = pool_.find(key);
if (it->second.get() == value) {

Modifications

  • Avoid dereferencing the iterator if it's invalid in ConnectionPool::remove.
  • Store the key suffix in ClientConnection and pass the correct key to ConnectionPool::remove in ClientConnection::close
  • Add ClientTest.testConnectionClose to verify ClientConnection::close can remove itself from the pool and the connection will be destroyed eventually.

@BewareMyPowerBewareMyPower self-assigned this Nov 16, 2023
@BewareMyPowerBewareMyPower added the bug Something isn't working label Nov 16, 2023
@BewareMyPower

Copy link
Copy Markdown
ContributorAuthor

More context: https://stackoverflow.com/questions/16267615/is-second-defined-for-iterator-stdmapend

Dereferencing an iterator that points to the end of a STL container is UB.

Fixesapache#346
### Motivation
apache#336 changes the key of
the `ClientConnection` in `ConnectionPool`, while in
`ClientConnection::close`, it still passes the old key (logical address)
to `ConnectionPool::remove`, which results in the connection could never
be removed and destroyed until being deleted as a stale connection.
What's worse, if the key does not exist, the iterator returned by
`std::map::find` will still be dereferenced, which might cause crash in
some platforms. See
https://github.com/apache/pulsar-client-cpp/blob/8d32fd254e294d1fabba73aed70115a434b341ef/lib/ConnectionPool.cc#L122-L123
### Modifications
- Avoid dereferencing the iterator if it's invalid in
`ConnectionPool::remove`.
- Store the key suffix in `ClientConnection` and pass the correct key to
`ConnectionPool::remove` in `ClientConnection::close`
- Add `ClientTest.testConnectionClose` to verify
`ClientConnection::close` can remove itself from the pool and the
connection will be destroyed eventually.
@BewareMyPower
BewareMyPowerforce-pushed the bewaremypower/fix-crash-cnx-per-broker branch from 270d36c to f90a9c3CompareNovember 16, 2023 04:50
@BewareMyPowerBewareMyPower added this to the 3.4.1 milestone Nov 16, 2023
@BewareMyPower
BewareMyPower merged commit 6d47e94 into apache:mainNov 17, 2023
@BewareMyPower
BewareMyPower deleted the bewaremypower/fix-crash-cnx-per-broker branch November 17, 2023 02:31
BewareMyPower added a commit that referenced this pull request Nov 17, 2023
Fixes#346
### Motivation
#336 changes the key of
the `ClientConnection` in `ConnectionPool`, while in
`ClientConnection::close`, it still passes the old key (logical address)
to `ConnectionPool::remove`, which results in the connection could never
be removed and destroyed until being deleted as a stale connection.
What's worse, if the key does not exist, the iterator returned by
`std::map::find` will still be dereferenced, which might cause crash in
some platforms. See
https://github.com/apache/pulsar-client-cpp/blob/8d32fd254e294d1fabba73aed70115a434b341ef/lib/ConnectionPool.cc#L122-L123
### Modifications
- Avoid dereferencing the iterator if it's invalid in
`ConnectionPool::remove`.
- Store the key suffix in `ClientConnection` and pass the correct key to
`ConnectionPool::remove` in `ClientConnection::close`
- Add `ClientTest.testConnectionClose` to verify
`ClientConnection::close` can remove itself from the pool and the
connection will be destroyed eventually.
(cherry picked from commit 6d47e94)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugSomething isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] ConnectionPool::remove Crash

2 participants

@BewareMyPower@RobertIndie