Merge pull request #15979 from jiangtaoli2016/fix_race
fix potential race condition in ALTS integrity-only extra-copy mode
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
index 54e59a6..352561d 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
@@ -42,34 +42,34 @@
static tsi_result alts_grpc_integrity_only_extra_copy_protect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
- /* Allocates memory for protected frame. */
+ /* Allocates memory for protected frame and copies data. */
+ size_t data_length = unprotected_slices->length;
size_t protected_frame_size =
unprotected_slices->length + rp->header_length + rp->tag_length;
grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
- /* Calls alts_iovec_record_protocol protect. */
- char* error_details = nullptr;
- iovec_t header_iovec = {GRPC_SLICE_START_PTR(protected_slice),
- rp->header_length};
- iovec_t tag_iovec = {GRPC_SLICE_START_PTR(protected_slice) +
- rp->header_length + unprotected_slices->length,
- rp->tag_length};
- alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp,
- unprotected_slices);
- grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect(
- rp->iovec_rp, rp->iovec_buf, unprotected_slices->count, header_iovec,
- tag_iovec, &error_details);
- if (status != GRPC_STATUS_OK) {
- gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
- gpr_free(error_details);
- return TSI_INTERNAL_ERROR;
- }
- /* Copies data from unprotected_slices to protected_slice. */
uint8_t* data = GRPC_SLICE_START_PTR(protected_slice) + rp->header_length;
for (size_t i = 0; i < unprotected_slices->count; i++) {
memcpy(data, GRPC_SLICE_START_PTR(unprotected_slices->slices[i]),
GRPC_SLICE_LENGTH(unprotected_slices->slices[i]));
data += GRPC_SLICE_LENGTH(unprotected_slices->slices[i]);
}
+ /* Calls alts_iovec_record_protocol protect. */
+ char* error_details = nullptr;
+ iovec_t header_iovec = {GRPC_SLICE_START_PTR(protected_slice),
+ rp->header_length};
+ iovec_t tag_iovec = {
+ GRPC_SLICE_START_PTR(protected_slice) + rp->header_length + data_length,
+ rp->tag_length};
+ rp->iovec_buf[0].iov_base =
+ GRPC_SLICE_START_PTR(protected_slice) + rp->header_length;
+ rp->iovec_buf[0].iov_len = data_length;
+ grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect(
+ rp->iovec_rp, rp->iovec_buf, 1, header_iovec, tag_iovec, &error_details);
+ if (status != GRPC_STATUS_OK) {
+ gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
+ gpr_free(error_details);
+ return TSI_INTERNAL_ERROR;
+ }
grpc_slice_buffer_add(protected_slices, protected_slice);
grpc_slice_buffer_reset_and_unref_internal(unprotected_slices);
return TSI_OK;