From 161547d5b6a179cf9c53dd3daffa7354a9f05765 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 17 Sep 2014 12:17:14 +0200 Subject: [PATCH] lib/socket.c: Fix a use-after-free This issue was introduced via patch "pdu: introduce ISCSI_PDU_CORK_WHEN_SENT" on June 13, 2014 (commit 99585b69968df1934415c6af3ad38fd1e35e6040). Valgrind reported this use-after-free as follows: Invalid read of size 4 at 0x5267606: iscsi_write_to_socket (socket.c:721) by 0x5267A72: iscsi_service (socket.c:823) by 0x526827C: event_loop (sync.c:67) by 0x52698A4: iscsi_compareandwrite_sync (sync.c:823) by 0x408111: compareandwrite (iscsi-support.c:1752) by 0x4139E2: test_compareandwrite_simple (test_compareandwrite_simple.c:88) by 0x503D260: ??? (in /usr/lib64/libcunit.so.1.0.1) by 0x503D578: ??? (in /usr/lib64/libcunit.so.1.0.1) by 0x503D8B5: CU_run_all_tests (in /usr/lib64/libcunit.so.1.0.1) by 0x4046C6: main (iscsi-test-cu.c:1241) Address 0x639f258 is 8 bytes inside a block of size 256 free'd at 0x4C291E7: free (vg_replace_malloc.c:473) by 0x525321B: iscsi_free (init.c:68) by 0x52532F0: iscsi_sfree (init.c:110) by 0x5257AD9: iscsi_free_pdu (pdu.c:179) by 0x5267601: iscsi_write_to_socket (socket.c:719) by 0x5267A72: iscsi_service (socket.c:823) by 0x526827C: event_loop (sync.c:67) by 0x52698A4: iscsi_compareandwrite_sync (sync.c:823) by 0x408111: compareandwrite (iscsi-support.c:1752) by 0x4139E2: test_compareandwrite_simple (test_compareandwrite_simple.c:88) by 0x503D260: ??? (in /usr/lib64/libcunit.so.1.0.1) by 0x503D578: ??? (in /usr/lib64/libcunit.so.1.0.1) Signed-off-by: Bart Van Assche Cc: Peter Lieven --- lib/socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/socket.c b/lib/socket.c index 2000678..cf414f5 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -715,12 +715,12 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) if (pdu->payload_written != total) { return 0; } - if (pdu->flags & ISCSI_PDU_DELETE_WHEN_SENT) { - iscsi_free_pdu(iscsi, pdu); - } if (pdu->flags & ISCSI_PDU_CORK_WHEN_SENT) { iscsi->is_corked = 1; } + if (pdu->flags & ISCSI_PDU_DELETE_WHEN_SENT) { + iscsi_free_pdu(iscsi, pdu); + } iscsi->outqueue_current = NULL; } return 0;