Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix S2N blocked issue #589

Merged
merged 16 commits into from
Aug 10, 2023
2 changes: 2 additions & 0 deletions include/aws/io/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ enum aws_io_errors {
AWS_IO_STREAM_SEEK_UNSUPPORTED,
AWS_IO_STREAM_GET_LENGTH_UNSUPPORTED,

AWS_IO_TLS_ERROR_READ_FAILURE,

AWS_IO_ERROR_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_IO_PACKAGE_ID),
AWS_IO_INVALID_FILE_HANDLE = AWS_ERROR_INVALID_FILE_HANDLE,
};
Expand Down
5 changes: 2 additions & 3 deletions source/darwin/secure_transport_tls_channel_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,8 @@ static int s_process_read_message(
(int)status);

if (status != errSSLClosedGraceful) {
aws_raise_error(AWS_IO_TLS_ERROR_ALERT_RECEIVED);
aws_channel_shutdown(
secure_transport_handler->parent_slot->channel, AWS_IO_TLS_ERROR_ALERT_RECEIVED);
aws_raise_error(AWS_IO_TLS_ERROR_READ_FAILURE);
aws_channel_shutdown(secure_transport_handler->parent_slot->channel, AWS_IO_TLS_ERROR_READ_FAILURE);
} else {
AWS_LOGF_TRACE(AWS_LS_IO_TLS, "id=%p: connection shutting down gracefully.", (void *)handler);
aws_channel_shutdown(secure_transport_handler->parent_slot->channel, AWS_ERROR_SUCCESS);
Expand Down
4 changes: 4 additions & 0 deletions source/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ static struct aws_error_info s_errors[] = {
AWS_DEFINE_ERROR_INFO_IO(
AWS_IO_STREAM_GET_LENGTH_UNSUPPORTED,
"Get length is not supported in the underlying I/O source."),
AWS_DEFINE_ERROR_INFO_IO(
AWS_IO_TLS_ERROR_READ_FAILURE,
"Failure during TLS read."),

};
/* clang-format on */

Expand Down
19 changes: 17 additions & 2 deletions source/s2n/s2n_tls_channel_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ static int s_s2n_handler_process_read_message(
AWS_LOGF_TRACE(
AWS_LS_IO_TLS, "id=%p: Downstream window %llu", (void *)handler, (unsigned long long)downstream_window);

while (processed < downstream_window && blocked == S2N_NOT_BLOCKED) {
while (processed < downstream_window) {

struct aws_io_message *outgoing_read_message = aws_channel_acquire_message_from_pool(
slot->channel, AWS_IO_MESSAGE_APPLICATION_DATA, downstream_window - processed);
Expand Down Expand Up @@ -558,9 +558,24 @@ static int s_s2n_handler_process_read_message(

if (read < 0) {
aws_mem_release(outgoing_read_message->allocator, outgoing_read_message);
continue;

/* the socket blocked so exit from the loop */
if (s2n_error_get_type(s2n_errno) == S2N_ERR_T_BLOCKED) {
break;
}

/* the socket returned a fatal error so shut down */
AWS_LOGF_ERROR(
AWS_LS_IO_TLS,
"id=%p: S2N failed to read with error: %s (%s)",
(void *)handler,
s2n_strerror(s2n_errno, "EN"),
s2n_strerror_debug(s2n_errno, "EN"));
aws_channel_shutdown(slot->channel, AWS_IO_TLS_ERROR_READ_FAILURE);
return AWS_OP_SUCCESS;
};

/* if read > 0 */
processed += read;
outgoing_read_message->message_data.len = (size_t)read;

Expand Down
6 changes: 3 additions & 3 deletions source/windows/secure_channel_tls_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ static int s_do_application_data_decrypt(struct aws_channel_handler *handler) {
int error = AWS_OP_ERR;
/* when we get an Extra buffer we have to move the pointer and replay the buffer, so we loop until we don't have
any extra buffers left over, in the last phase, we then go ahead and send the output. This state function will
always say BLOCKED_ON_READ or SUCCESS. There will never be left over reads.*/
always say BLOCKED_ON_READ, AWS_IO_TLS_ERROR_READ_FAILURE or SUCCESS. There will never be left over reads.*/
do {
error = AWS_OP_ERR;
/* 4 buffers are needed, only one is input, the others get zeroed out for the output operation. */
Expand All @@ -1079,6 +1079,7 @@ static int s_do_application_data_decrypt(struct aws_channel_handler *handler) {
SECURITY_STATUS status = DecryptMessage(&sc_handler->sec_handle, &buffer_desc, 0, NULL);

if (status == SEC_E_OK) {
error = AWS_OP_SUCCESS;
/* if SECBUFFER_DATA is the buffer type of the second buffer, we have decrypted data to process.
If SECBUFFER_DATA is the type for the fourth buffer we need to keep track of it so we can shift
everything before doing another decrypt operation.
Expand Down Expand Up @@ -1144,8 +1145,7 @@ static int s_do_application_data_decrypt(struct aws_channel_handler *handler) {
} else {
AWS_LOGF_ERROR(
AWS_LS_IO_TLS, "id=%p: Error decrypting message. SECURITY_STATUS is %d.", (void *)handler, (int)status);
int aws_error = s_determine_sspi_error(status);
aws_raise_error(aws_error);
aws_raise_error(AWS_IO_TLS_ERROR_READ_FAILURE);
}
} while (sc_handler->read_extra);

Expand Down