Skip to content

ares_gethostbyname() and exception safety #219

@htuch

Description

@htuch

While investigating a memory leak in Envoy (spotted by https://github.com/google/oss-fuzz), a c-ares consumer, I noticed the following trace:

Direct leak of 8 byte(s) in 1 object(s) allocated from:
--
  | #0 0x4e7a78 in __interceptor___strdup _asan_rtl_
  | #1 0x279fba4 in fake_hostent /builder/home/.cache/bazel/_bazel_root/4e9824db8e7d11820cfa25090ed4ed10/external/envoy_deps_cache_b22e04bff96538ea37e715942da6315c/cares.dep.build/c-ares-cares-1_14_0/ares_gethostbyname.c:290:20
  | #2 0x279fba4 in ares_gethostbyname /builder/home/.cache/bazel/_bazel_root/4e9824db8e7d11820cfa25090ed4ed10/external/envoy_deps_cache_b22e04bff96538ea37e715942da6315c/cares.dep.build/c-ares-cares-1_14_0/ares_gethostbyname.c:98
  | #3 0x8cb8c5 in Envoy::Network::DnsResolverImpl::resolve(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, Envoy::Network::DnsLookupFamily, std::__1::function<void (std::__1::list<std::__1::shared_ptr<Envoy::Network::Address::Instance const>, std::__1::allocator<std::__1::shared_ptr<Envoy::Network::Address::Instance const> > >&&)>) /source/common/network/dns_impl.cc:196:25
  | #4 0x1530264 in Envoy::Upstream::StrictDnsClusterImpl::ResolveTarget::startResolve() /source/common/upstream/upstream_impl.cc:1138:42

what's happening is we're doing a DNS resolution on an IP address, the strdup at

hostent.h_name = ares_strdup(name);
allocates, and Envoy code is throwing an exception in the callback at
callback(arg, ARES_ENOMEM, 0, NULL);
. This then prevents the free at
ares_free((char *)(hostent.h_name));
from happening.

There are two ways to fix this:

  1. Make c-ares more robust to exceptions. I'm not sure how broad the issues around c-ares, callbacks and exceptions are, hoping the maintainers of this project can shed some light here.
  2. If exceptions can't happen in callbacks, force Envoy to be exception free in any c-ares callback. This is possible but might involve some rearchitecting of how we handle resolution. CC @envoyproxy/maintainers

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions