HTTPClient POST body helper can dereference a released unique_ptr

Open Beginner friendly
#642 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
cpp
Domain
networking

Research direction

Start in proxygen/lib/http/coro/client/HTTPClient.cpp at HTTPClient::post() and the internal stringToIOBuf() helper around the referenced lines. Replace the unsafe takeOwnership() argument evaluation so no argument dereferences the unique_ptr after another releases it. Confirm that non-empty HTTP/1.1 POST requests construct their body without the null dereference while GET and empty-body paths remain unaffected.

Written by the indexing model from the issue text.

Description

Problem

proxygen::coro::HTTPClient::post() can dereference a null pointer while constructing a non-empty request body. The internal stringToIOBuf() helper evaluates accesses to a std::unique_ptr and release() in the same argument list:

auto strPtr = std::make_unique<std::string>(std::move(str).value());
strBuf = folly::IOBuf::takeOwnership(
    strPtr->data(),
    strPtr->size(),
    [](void*, void* data) { delete static_cast<std::string*>(data); },
    strPtr.release());

C++ does not specify the order of evaluation of these arguments. If the last argument is evaluated first, release() clears strPtr, and evaluating either of the first two arguments then dereferences null. This is not a coroutine lifetime issue: the problem is within this single call expression.

The code is still present on upstream main at 6bd0ee43ad0709df359f2bcdb9137cc63b0dc43a.

Trigger and observations

An HTTP/1.1 POST to a local server, with a non-empty body, enters this path:

co_await proxygen::coro::HTTPClient::post(
    evb, "http://127.0.0.1:8080/anything", "{\"a\":1}",
    std::chrono::seconds{5}, false,
    {{"content-type", "application/json"}});

We observed a SIGSEGV on x86-64 Linux with a dependency based on release v2026.06.29.00; the corresponding test passes on arm64 macOS. The crash's async stack goes through HTTPClient::post(). The innermost CI frames are not symbolized, so this report distinguishes the definite source-level defect from full confirmation of that particular crash location.

GET and empty-body POST requests skip the offending block. A caller can avoid it by constructing an HTTPFixedSource with an owned IOBuf and using the HTTPClient::request() overload that accepts an HTTPSourceHolder.

Suggested fix

Use folly::IOBuf::fromString(std::move(*str)), or evaluate strPtr->data() and strPtr->size() into locals before the takeOwnership() call. In either case, no argument should dereference the pointer that another argument releases.

Dominant language
C++
Stars
8.4k
Forks
1.5k
Avg merge
10m
Merged PRs (30d)
2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from facebook/proxygen

All issues in facebook/proxygen

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.