When to free bufferevent+http+mbedtls context

Open
#1,808 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Bug
Clarity
Needs clarification
Activity status
Stale
Tech stack
c
Domain
networking

Research direction

Read event/event_rest.c alongside sample/https-client.c, then trace bufferevent_finalize_cb_ and bufferevent_mbedtls_dyncontext_free to establish the callback and cleanup order. Review the proposed callback in the linked patch and determine whether it provides a safe ownership boundary. Done means documenting or implementing an agreed lifetime strategy without the reported use-after-free crash.

Written by the indexing model from the issue text.

Description

I'm creating a HTTP request with evhttp_request_new, which is made using a HTTP connection associated to a bufferevent. As I understand, this will ultimately trigger an event chain in bufferevent, which can invoke events even after we call evhttp_connection_free (which in turn calls bufferevent_free). If I'm not mistaken, this is also true even if we are doing evhttp_connection_free_on_completion, to avoid manually freeing stuff.

You can see my code here, which is based on this sample.

As you can see in the code, to keep things simple, I am storing all mbedtls context in a struct that is passed as an argument to evhttp_request_new. This allows for a context-free rest header.

Then, my first idea was to free that context later in its callback, which will cause a crash because of the mentioned chain of events that might be invoked after the callback and even after evhttp_connection_free. This is the context:

typedef struct {
    mbedtls_x509_crt cacert;
    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_entropy_context entropy;
    mbedtls_ssl_config config;

    struct bufferevent *bev;
    struct evhttp_connection *evcon;
    mbedtls_dyncontext *ssl;
} mbedtls_ctx_t;

Specifically, the crash is happening because of doing this...:

    mbedtls_x509_crt_free(&ctx->cacert);
    mbedtls_ssl_config_free(&ctx->config);
    mbedtls_ctr_drbg_free(&ctx->ctr_drbg);
    mbedtls_entropy_free(&ctx->entropy);

    free(ctx);

...before, internally, the library executing bufferevent_finalize_cb_, which is calling some destruct pointer function that ends up calling bufferevent_mbedtls_dyncontext_free.

To solve this, I ended up adding a new callback that is executed once bufferevent has finished all of its chain of events (I think) and once bufferevent_mbedtls_dyncontext_free has been executed by the library (that's for sure). See the patch here.

Is this a good approach to solve this problem or am I overkilling it?

Dominant language
C
Stars
12k
Forks
3.5k
Avg merge
12h 55m
Merged PRs (30d)
6

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 libevent/libevent

All issues in libevent/libevent

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.