Skip to content

fix(kafka): fix use-after-free on task cancellation during kafka producer Send#1299

Open
disaykin wants to merge 2 commits into
userver-framework:developfrom
disaykin:kafka-producer-cancellation-fix
Open

fix(kafka): fix use-after-free on task cancellation during kafka producer Send#1299
disaykin wants to merge 2 commits into
userver-framework:developfrom
disaykin:kafka-producer-cancellation-fix

Conversation

@disaykin

Copy link
Copy Markdown
Contributor

Fixes a Use-After-Free vulnerability in the asynchronous Kafka Producer API when a task is cancelled before librdkafka flushes its queue.

The kafka::Producer::Send API accepts parameters as views (string_view, zstring_view, HeaderViews). These views point to data owned by the caller. Inside Send, raw pointers from these views are passed down to librdkafka, which stores them in its internal asynchronous queues for background delivery.

If a client connection drops, a cascade cancellation of tasks occurs. This leads to a premature return from kafka::Producer::Send, causing the caller to destroy the original payload memory. However, librdkafka still retains these pointers and attempts to access them during subsequent network flushes to the broker, resulting in memory corruption.

To fix this, we ensure that Producer::Send is blocked from returning prematurely and cannot exit until the background SendImpl completes its interaction with librdkafka.


Note: by creating a PR or an issue you automatically agree to the CLA. See CONTRIBUTING.md. Feel free to remove this note, the agreement holds.

…ucer Send

Fixes a Use-After-Free vulnerability in the asynchronous Kafka Producer API when
a task is cancelled before librdkafka flushes its queue.

The `kafka::Producer::Send` API accepts parameters as views (`string_view`,
`zstring_view`, `HeaderViews`). These views point to data owned by the caller.
Inside `Send`, raw pointers from these views are passed down to `librdkafka`,
which stores them in its internal asynchronous queues for background delivery.

If a client connection drops, a cascade cancellation of tasks occurs. This
leads to a premature return from `kafka::Producer::Send`, causing the caller
to destroy the original payload memory. However, `librdkafka` still retains
these pointers and attempts to access them during subsequent network flushes
to the broker, resulting in memory corruption.

To fix this, we ensure that `Producer::Send` is blocked from returning
prematurely and cannot exit until the background `SendImpl` completes
its interaction with `librdkafka`.

Co-authored-by: Aleksander Rypalov <rypalov2002@gmail.com>
@disaykin
disaykin force-pushed the kafka-producer-cancellation-fix branch from 30e88de to 82e223b Compare July 17, 2026 09:01
@disaykin

Copy link
Copy Markdown
Contributor Author

@apolukhin прошу ревью. проблему с установкой кафки в тестах я починил (там протух урл), но вот что делать с флапающим тестом на постгрю - не знаю:

[ RUN      ] PoolTests/PostgrePool.PoolServerUnavailable/Sync
userver/postgresql/src/storages/postgres/tests/pool_pgtest.cpp:313: Failure
Expected equality of these values:
  0
  stats.connection.active
    Which is: 1

[  FAILED  ] PoolTests/PostgrePool.PoolServerUnavailable/Sync, where GetParam() = 4-byte object <00-00 00-00> (2013 ms)

Но это точно не относится к моему фиксу.

Также проблема компиляции с rabbitmq на debian12 привнесена не мной/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant