[client_channel] Fix use-after-free (#33239)

recv_initial_metadata_ in `RetryFilter::CallAttempt` is deleted before
it's accessed in
`ClientChannel::FilterBasedLoadBalancedCall::RecvTrailingMetadataReady`
- instead of accessing it, pull out peer string and keep a ref
pull/33247/head
Craig Tiller 2 years ago committed by GitHub
parent eb2b1edd1c
commit 02693313f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      src/core/ext/filters/client_channel/client_channel.cc
  2. 2
      src/core/ext/filters/client_channel/client_channel.h

@ -3017,6 +3017,8 @@ void ClientChannel::FilterBasedLoadBalancedCall::RecvInitialMetadataReady(
// recv_initial_metadata_flags is not populated for clients
self->call_attempt_tracer()->RecordReceivedInitialMetadata(
self->recv_initial_metadata_);
auto* peer_string = self->recv_initial_metadata_->get_pointer(PeerString());
if (peer_string != nullptr) self->peer_string_ = peer_string->Ref();
}
Closure::Run(DEBUG_LOCATION, self->original_recv_initial_metadata_ready_,
error);
@ -3060,12 +3062,8 @@ void ClientChannel::FilterBasedLoadBalancedCall::RecvTrailingMetadataReady(
}
}
absl::string_view peer_string;
if (self->recv_initial_metadata_ != nullptr) {
Slice* peer_string_slice =
self->recv_initial_metadata_->get_pointer(PeerString());
if (peer_string_slice != nullptr) {
peer_string = peer_string_slice->as_string_view();
}
if (self->peer_string_.has_value()) {
peer_string = self->peer_string_->as_string_view();
}
self->RecordCallCompletion(status, self->recv_trailing_metadata_,
self->transport_stream_stats_, peer_string);

@ -65,6 +65,7 @@
#include "src/core/lib/resolver/resolver.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/service_config/service_config.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/metadata_batch.h"
@ -556,6 +557,7 @@ class ClientChannel::FilterBasedLoadBalancedCall
CallCombiner* call_combiner_;
grpc_polling_entity* pollent_;
grpc_closure* on_call_destruction_complete_;
absl::optional<Slice> peer_string_;
// Set when we get a cancel_stream op.
grpc_error_handle cancel_error_;

Loading…
Cancel
Save