From 5cb77051cedd9b5548aef8412154ed916b286e59 Mon Sep 17 00:00:00 2001 From: hongleiwang Date: Wed, 4 Dec 2024 17:40:22 +0800 Subject: [PATCH] fix: scan PDUs before exiting event_loop due to connect timedout In iSCSI synchronous operations, a struct iscsi_sync_state variable (state) is allocated on the stack, and its address is assigned to pdu->scsi_cbdata.private_data. This address is eventually used in the PDU callback function. However, if a reconnection occurs during a synchronous operation (e.g., read or write), but the connect function fails (iscsi->fd will be set to -1), the event_loop times out and exits. At this point, unprocessed PDUs remain. If the PDU callback function is triggered after the timeout (e.g., during iscsi_destroy_context), it may access the pdu->scsi_cbdata.private_data address, which no longer points to the original stack allocation. Writing to this invalid address in the callback corrupts the current stack structure, leading to process crash. This patch addresses the issue by scanning PDUs before exiting the event_loop due connect timedout, ensuring the unprocessed PDUs are properly handled to prevent stack corruption and crash. Signed-off-by: raywang --- lib/sync.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/sync.c b/lib/sync.c index abbae9e..3e987da 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -67,14 +67,21 @@ event_loop(struct iscsi_context *iscsi, struct iscsi_sync_state *state) while (state->finished == 0) { short revents; - if (scsi_timeout) { - t = time(NULL); - if (t > scsi_timeout) { - iscsi_set_error(iscsi, "Connect timedout"); - state->status = -1; - return; - } - } + if (scsi_timeout) { + t = time(NULL); + if (t > scsi_timeout) { + iscsi_timeout_scan(iscsi); + + if (iscsi->old_iscsi) { + iscsi_timeout_scan(iscsi->old_iscsi); + } + + iscsi_set_error(iscsi, "Connect timedout"); + state->status = -1; + return; + } + } + pfd.fd = iscsi_get_fd(iscsi); pfd.events = iscsi_which_events(iscsi);