Skip to content

Segfault when referencing SDS secrets by name with default validation context #7892

@snowp

Description

@snowp

Using the following TLS config for a cluster:

tls_context {
  common_tls_context {
    tls_params {
      tls_minimum_protocol_version: TLSv1_2
    }
    alpn_protocols: "h2"
    alpn_protocols: "http/1.1"
    tls_certificate_sds_secret_configs {
      name: "s2s-certificate"
    }
    combined_validation_context {
      default_validation_context {
        verify_subject_alt_name: "whatever"
      }
      validation_context_sds_secret_config {
        name: "s2s-ca"
      }
    }
  }
}

with a static secret defined in the bootstrap as

        .addSecrets(Secret.newBuilder()
            .setName("s2s-certificate")
            .setTlsCertificate(TlsCertificate.newBuilder()
                .setCertificateChain(DataPlaneProtoUtils.fileLocation(CRT_PATH))
                .setPrivateKey(DataPlaneProtoUtils.fileLocation(KEY_PATH))))
        .addSecrets(Secret.newBuilder()
            .setName("s2s-ca")
            .setValidationContext(CertificateValidationContext.newBuilder()
                .setTrustedCa(DataPlaneProtoUtils.fileLocation(CA_PATH))))

a crash occurs in ContextConfigImpl::ContextConfigImpl due to a bad dynamic cast:

    cvc_validation_callback_handle_ =
        dynamic_cast<Secret::CertificateValidationContextSdsApi*>(
            certificate_validation_context_provider_.get())
            ->addValidationCallback(
                [this](const envoy::api::v2::auth::CertificateValidationContext& dynamic_cvc) {
                  getCombinedValidationContextConfig(dynamic_cvc);
                });

as certificate_validation_context_provider_ doesn't point to a CertificateValidationContextSdsApi:

(gdb) p *certificate_validation_context_provider_._M_ptr
$4 = {_vptr$SecretProvider = 0x32f020 <vtable for Envoy::Secret::CertificateValidationContextConfigProviderImpl+16>}

Full back trace:

#0  0x000000000131a2f0 in std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*) ()
#1  0x0000000000b911ac in std::__cxx11::list<Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>::CallbackHolder, std::allocator<Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>::CallbackHolder> >::_M_insert<Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>&, std::function<void (envoy::api::v2::auth::CertificateValidationContext const&)>&>(std::_List_iterator<Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>::CallbackHolder>, Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>&, std::function<void (envoy::api::v2::auth::CertificateValidationContext const&)>&) (this=0x100, __position=..., __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_list.h:1802
#2  std::__cxx11::list<Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>::CallbackHolder, std::allocator<Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>::CallbackHolder> >::emplace_back<Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>&, std::function<void (envoy::api::v2::auth::CertificateValidationContext const&)>&>(Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>&, std::function<void (envoy::api::v2::auth::CertificateValidationContext const&)>&) (this=0x100, __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_list.h:1133
#3  Envoy::Common::CallbackManager<envoy::api::v2::auth::CertificateValidationContext const&>::add(std::function<void (envoy::api::v2::auth::CertificateValidationContext const&)>) (this=0x100, callback=...)
    at bazel-out/k8-opt/bin/source/common/common/_virtual_includes/callback_impl_lib/common/common/callback_impl.h:26
#4  Envoy::Secret::CertificateValidationContextSdsApi::addValidationCallback(std::function<void (envoy::api::v2::auth::CertificateValidationContext const&)>) (this=0x0, callback=...) at bazel-out/k8-opt/bin/source/common/secret/_virtual_includes/sds_api_lib/common/secret/sds_api.h:163
#5  0x0000000000b90255 in Envoy::Extensions::TransportSockets::Tls::ContextConfigImpl::ContextConfigImpl (this=0x258f040, vtt=<optimized out>,
    config=..., default_min_protocol_version=769, default_max_protocol_version=771, default_cipher_suites=..., default_curves=...,
    factory_context=...) at source/extensions/transport_sockets/tls/context_config_impl.cc:138
#6  0x0000000000b91e16 in Envoy::Extensions::TransportSockets::Tls::ClientContextConfigImpl::ClientContextConfigImpl (this=0x258f040, config=...,
    sigalgs=..., factory_context=...) at source/extensions/transport_sockets/tls/context_config_impl.cc:274
#7  0x0000000000b89721 in Envoy::Extensions::TransportSockets::Tls::ClientContextConfigImpl::ClientContextConfigImpl (this=0x258f040, config=...,
    secret_provider_context=...)
    at bazel-out/k8-opt/bin/source/extensions/transport_sockets/tls/_virtual_includes/context_config_lib/extensions/transport_sockets/tls/context_config_impl.h:105
#8  std::make_unique<Envoy::Extensions::TransportSockets::Tls::ClientContextConfigImpl, envoy::api::v2::auth::UpstreamTlsContext const&, Envoy::Server::Configuration::TransportSocketFactoryContext&> (__args=..., __args=...)
    at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/unique_ptr.h:825
#9  Envoy::Extensions::TransportSockets::Tls::UpstreamSslSocketFactory::createTransportSocketFactory (this=<optimized out>, message=..., context=...)
    at source/extensions/transport_sockets/tls/config.cc:19
#10 0x0000000000d72f50 in Envoy::Upstream::createTransportSocketFactory (config=..., factory_context=...)
    at source/common/upstream/upstream_impl.cc:675
#11 0x0000000000d7319e in Envoy::Upstream::ClusterImplBase::ClusterImplBase (this=0x220f8d0, cluster=..., runtime=..., factory_context=...,
    stats_scope=..., added_via_api=<optimized out>) at source/common/upstream/upstream_impl.cc:686
#12 0x0000000000d81e2f in Envoy::Upstream::BaseDynamicClusterImpl::ClusterImplBase (this=0x220f8d0)
    at bazel-out/k8-opt/bin/source/common/upstream/_virtual_includes/upstream_includes/common/upstream/upstream_impl.h:799
#13 Envoy::Upstream::EdsClusterImpl::EdsClusterImpl (this=0x220f8d0, cluster=..., runtime=..., factory_context=..., stats_scope=...,
    added_via_api=<optimized out>) at source/common/upstream/eds.cc:14
--Type <RET> for more, q to quit, c to continue without paging--
#14 0x0000000000d853c3 in __gnu_cxx::new_allocator<Envoy::Upstream::EdsClusterImpl>::construct<Envoy::Upstream::EdsClusterImpl, envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (this=<optimized out>, __p=0x23bf480, __args=<optimized out>, __args=<optimized out>, __args=<optimized out>,
    __args=<optimized out>, __args=<optimized out>) at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/ext/new_allocator.h:136
#15 std::allocator_traits<std::allocator<Envoy::Upstream::EdsClusterImpl> >::construct<Envoy::Upstream::EdsClusterImpl, envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (__a=..., __p=0x23bf480, __args=<optimized out>, __args=<optimized out>, __args=<optimized out>, __args=<optimized out>,
    __args=<optimized out>) at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/alloc_traits.h:475
#16 std::_Sp_counted_ptr_inplace<Envoy::Upstream::EdsClusterImpl, std::allocator<Envoy::Upstream::EdsClusterImpl>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (this=<optimized out>, __args=<optimized out>, __args=<optimized out>,
    __args=<optimized out>, __args=<optimized out>, __a=..., __args=<optimized out>)
    at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:526
#17 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<Envoy::Upstream::EdsClusterImpl, std::allocator<Envoy::Upstream::EdsClusterImpl>, envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (this=<optimized out>, __a=..., __args=<optimized out>, __args=<optimized out>,
    __args=<optimized out>, __args=<optimized out>, __args=<optimized out>)
    at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:637
#18 std::__shared_ptr<Envoy::Upstream::EdsClusterImpl, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Envoy::Upstream::EdsClusterImpl>, envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (this=<optimized out>, __a=..., __args=<optimized out>, __args=<optimized out>,
    __args=<optimized out>, __args=<optimized out>, __tag=..., __args=<optimized out>)
    at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr_base.h:1294
#19 std::shared_ptr<Envoy::Upstream::EdsClusterImpl>::shared_ptr<std::allocator<Envoy::Upstream::EdsClusterImpl>, envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (this=<optimized out>, __a=..., __args=<optimized out>, __args=<optimized out>, __args=<optimized out>, __args=<optimized out>,
    __tag=..., __args=<optimized out>) at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr.h:344
#20 std::allocate_shared<Envoy::Upstream::EdsClusterImpl, std::allocator<Envoy::Upstream::EdsClusterImpl>, envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (__a=..., __args=<optimized out>, __args=<optimized out>, __args=<optimized out>, __args=<optimized out>, __args=<optimized out>)
    at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr.h:690
#21 std::make_shared<Envoy::Upstream::EdsClusterImpl, envoy::api::v2::Cluster const&, Envoy::Runtime::Loader&, Envoy::Server::Configuration::TransportSocketFactoryContext&, std::unique_ptr<Envoy::Stats::Scope, std::default_delete<Envoy::Stats::Scope> >, bool> (__args=<optimized out>,
    __args=<optimized out>, __args=<optimized out>, __args=<optimized out>, __args=<optimized out>)
    at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/shared_ptr.h:706
#22 Envoy::Upstream::EdsClusterFactory::createClusterImpl (this=<optimized out>, cluster=..., context=..., socket_factory_context=...,
    stats_scope=...) at source/common/upstream/eds.cc:270
#23 0x0000000000d9019f in Envoy::Upstream::ClusterFactoryImplBase::create (this=0x1397050 <Envoy::Upstream::EdsClusterFactory_registered>,
    cluster=..., context=...) at source/common/upstream/cluster_factory_impl.cc:103
--Type <RET> for more, q to quit, c to continue without paging--
#24 0x0000000000d8f434 in Envoy::Upstream::ClusterFactoryImplBase::create (cluster=..., cluster_manager=..., stats=..., tls=..., dns_resolver=...,
    ssl_context_manager=..., runtime=..., random=..., dispatcher=..., log_manager=..., local_info=..., admin=..., singleton_manager=...,
    outlier_event_logger=..., added_via_api=<optimized out>, validation_visitor=..., api=...) at source/common/upstream/cluster_factory_impl.cc:68
#25 0x0000000000c4bc12 in Envoy::Upstream::ProdClusterManagerFactory::clusterFromProto (this=<optimized out>, cluster=..., cm=...,
    outlier_event_logger=..., added_via_api=<optimized out>) at source/common/upstream/cluster_manager_impl.cc:1267
#26 0x0000000000c405e1 in Envoy::Upstream::ClusterManagerImpl::loadCluster (this=0x22fcf00, cluster=..., version_info=...,
    added_via_api=<optimized out>, cluster_map=...) at source/common/upstream/cluster_manager_impl.cc:584
#27 0x0000000000c4283f in Envoy::Upstream::ClusterManagerImpl::addOrUpdateCluster (this=0x22fcf00, cluster=..., version_info=...)
    at source/common/upstream/cluster_manager_impl.cc:486
#28 0x0000000000c5644c in Envoy::Upstream::CdsApiImpl::onConfigUpdate (this=<optimized out>, added_resources=..., removed_resources=...,
    system_version_info=...) at source/common/upstream/cds_api_impl.cc:76
#29 0x0000000000c55e9e in Envoy::Upstream::CdsApiImpl::onConfigUpdate (this=0x239dc00, resources=..., version_info=...)
    at source/common/upstream/cds_api_impl.cc:53
#30 0x0000000000da130a in Envoy::Config::GrpcMuxSubscriptionImpl::onConfigUpdate (this=0x239f050, resources=..., version_info=...)
    at source/common/config/grpc_mux_subscription_impl.cc:56
#31 0x0000000000d9e596 in Envoy::Config::GrpcMuxImpl::onDiscoveryResponse (this=0x231b900, message=...) at source/common/config/grpc_mux_impl.cc:174
#32 0x0000000000d9f253 in Envoy::Grpc::AsyncStreamCallbacks<envoy::api::v2::DiscoveryResponse>::onReceiveMessageRaw (this=0x231b910, response=...)
    at bazel-out/k8-opt/bin/source/common/grpc/_virtual_includes/typed_async_client_lib/common/grpc/typed_async_client.h:89
#33 0x0000000000dc53d7 in Envoy::Grpc::AsyncStreamImpl::onData (this=0x2254750, data=..., end_stream=<optimized out>)
    at source/common/grpc/async_client_impl.cc:138
#34 0x0000000000dc9df4 in Envoy::Http::AsyncStreamImpl::encodeData (this=0x23b8800, data=..., end_stream=<optimized out>)
    at source/common/http/async_client_impl.cc:101
#35 0x0000000000e3c127 in Envoy::Http::Http2::ConnectionImpl::onFrameReceived (this=0x239f838, frame=0x22533a0)
    at source/common/http/http2/codec_impl.cc:490
#36 0x0000000000e407cc in Envoy::Http::Http2::ConnectionImpl::Http2Callbacks::Http2Callbacks()::$_8::operator()(nghttp2_session*, nghttp2_frame const*, void*) const (this=<optimized out>, frame=0x100, user_data=0x23bf480) at source/common/http/http2/codec_impl.cc:799
#37 Envoy::Http::Http2::ConnectionImpl::Http2Callbacks::Http2Callbacks()::$_8::__invoke(nghttp2_session*, nghttp2_frame const*, void*) (frame=0x100,
    user_data=0x23bf480) at source/common/http/http2/codec_impl.cc:798
#38 0x0000000000e497cf in session_call_on_frame_received (session=<optimized out>, frame=<optimized out>)
    at /build/tmp/_bazel_bazel/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/external/com_github_nghttp2_nghttp2/lib/nghttp2_session.c:3295
#39 nghttp2_session_on_data_received (session=0x2253200, frame=0x22533a0)
    at /build/tmp/_bazel_bazel/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/external/com_github_nghttp2_nghttp2/lib/nghttp2_session.c:4966
#40 0x0000000000e4b4a7 in session_process_data_frame (session=<optimized out>)
    at /build/tmp/_bazel_bazel/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/external/com_github_nghttp2_nghttp2/lib/nghttp2_session.c:4986
#41 nghttp2_session_mem_recv (session=<optimized out>, in=0x22bc8a0 "\300\357%\002", inlen=<optimized out>)
    at /build/tmp/_bazel_bazel/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/external/com_github_nghttp2_nghttp2/lib/nghttp2_session.c:6607
#42 0x0000000000e3ba76 in Envoy::Http::Http2::ConnectionImpl::dispatch (this=0x239f838, data=...) at source/common/http/http2/codec_impl.cc:350
#43 0x0000000000db9b96 in Envoy::Http::CodecClient::onData (this=0x239f7a0, data=...) at source/common/http/codec_client.cc:116
#44 0x0000000000dba62d in Envoy::Http::CodecClient::CodecReadFilter::onData (this=<optimized out>, data=...)
--Type <RET> for more, q to quit, c to continue without paging--
    at bazel-out/k8-opt/bin/source/common/http/_virtual_includes/codec_client_lib/common/http/codec_client.h:172
#45 0x0000000000c17611 in Envoy::Network::FilterManagerImpl::onContinueReading (this=0x235a928, filter=<optimized out>, buffer_source=...)
    at source/common/network/filter_manager_impl.cc:65
#46 0x0000000000c13fcc in Envoy::Network::ConnectionImpl::onRead (this=<optimized out>, read_buffer_size=<optimized out>)
    at source/common/network/connection_impl.cc:269
#47 Envoy::Network::ConnectionImpl::onReadReady (this=0x235a900) at source/common/network/connection_impl.cc:513
#48 0x0000000000c13a91 in Envoy::Network::ConnectionImpl::onFileEvent (this=0x235a900, events=<optimized out>)
    at source/common/network/connection_impl.cc:489
#49 0x0000000000c0e735 in std::function<void (unsigned int)>::operator()(unsigned int) const (this=0x23bf480, __args=3)
    at /usr/lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/std_function.h:706
#50 Envoy::Event::FileEventImpl::assignEvents(unsigned int)::$_0::operator()(int, short, void*) const (this=<optimized out>, what=<optimized out>,
    arg=0x3) at source/common/event/file_event_impl.cc:65
#51 Envoy::Event::FileEventImpl::assignEvents(unsigned int)::$_0::__invoke(int, short, void*) (what=<optimized out>, arg=0x3)
    at source/common/event/file_event_impl.cc:49
#52 0x0000000000fbe39d in event_process_active_single_queue ()
#53 0x0000000000fbc950 in event_base_loop ()

Traces taken from 3d6d6fa, but this also reproduces on latest master (I didn't check to see if the back trace changed).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions