[Promises] Fix use after free in promise based client call (#32747)

Discovered testing #32603 

<!--

If you know who should review your pull request, please assign it to
that
person, otherwise the pull request would get assigned randomly.

If your pull request is for a specific language, please add the
appropriate
lang label.

-->
pull/32759/head
Craig Tiller 2 years ago committed by GitHub
parent 656e5f283b
commit e4b63015ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/core/lib/surface/call.cc

@ -2739,6 +2739,10 @@ class ClientPromiseBasedCall final : public PromiseBasedCall {
// In the latter case real world code sometimes does not sent the initial // In the latter case real world code sometimes does not sent the initial
// metadata, and so gating based upon that does not work out. // metadata, and so gating based upon that does not work out.
std::atomic<bool> started_{false}; std::atomic<bool> started_{false};
// TODO(ctiller): delete when we remove the filter based API (may require some
// cleanup in wrapped languages: they depend on this to hold slice refs)
ServerMetadataHandle recv_initial_metadata_;
ServerMetadataHandle recv_trailing_metadata_;
}; };
void ClientPromiseBasedCall::StartPromise( void ClientPromiseBasedCall::StartPromise(
@ -2919,6 +2923,7 @@ void ClientPromiseBasedCall::StartRecvInitialMetadata(
} }
ProcessIncomingInitialMetadata(*metadata); ProcessIncomingInitialMetadata(*metadata);
PublishMetadataArray(metadata.get(), array); PublishMetadataArray(metadata.get(), array);
recv_initial_metadata_ = std::move(metadata);
FinishOpOnCompletion(&completion, PendingOp::kReceiveInitialMetadata); FinishOpOnCompletion(&completion, PendingOp::kReceiveInitialMetadata);
}); });
} }
@ -3000,6 +3005,7 @@ void ClientPromiseBasedCall::StartRecvStatusOnClient(
} }
PublishMetadataArray(trailing_metadata.get(), PublishMetadataArray(trailing_metadata.get(),
op_args.trailing_metadata); op_args.trailing_metadata);
recv_trailing_metadata_ = std::move(trailing_metadata);
FinishOpOnCompletion(&completion, PendingOp::kReceiveStatusOnClient); FinishOpOnCompletion(&completion, PendingOp::kReceiveStatusOnClient);
}); });
} }

Loading…
Cancel
Save