Module Name: src Committed By: mlelstv Date: Sat Aug 24 09:39:44 UTC 2024
Modified Files: src/sys/dev/iscsi: iscsi_ioctl.c iscsi_send.c Log Message: Avoid race in timeout handling. Don't try to wake up CCB without connection (which led to a NULL pointer deref). To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/dev/iscsi/iscsi_ioctl.c cvs rdiff -u -r1.40 -r1.41 src/sys/dev/iscsi/iscsi_send.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/iscsi/iscsi_ioctl.c diff -u src/sys/dev/iscsi/iscsi_ioctl.c:1.34 src/sys/dev/iscsi/iscsi_ioctl.c:1.35 --- src/sys/dev/iscsi/iscsi_ioctl.c:1.34 Sat Nov 25 10:08:27 2023 +++ src/sys/dev/iscsi/iscsi_ioctl.c Sat Aug 24 09:39:44 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: iscsi_ioctl.c,v 1.34 2023/11/25 10:08:27 mlelstv Exp $ */ +/* $NetBSD: iscsi_ioctl.c,v 1.35 2024/08/24 09:39:44 mlelstv Exp $ */ /*- * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc. @@ -1635,9 +1635,11 @@ connection_timeout_co(void *par) connection_t *conn = par; mutex_enter(&iscsi_cleanup_mtx); - conn->c_timedout = TOUT_QUEUED; - TAILQ_INSERT_TAIL(&iscsi_timeout_conn_list, conn, c_tchain); - iscsi_notify_cleanup(); + if (conn->c_timedout == TOUT_ARMED) { + conn->c_timedout = TOUT_QUEUED; + TAILQ_INSERT_TAIL(&iscsi_timeout_conn_list, conn, c_tchain); + iscsi_notify_cleanup(); + } mutex_exit(&iscsi_cleanup_mtx); } @@ -1657,14 +1659,13 @@ connection_timeout_stop(connection_t *co { callout_stop(&conn->c_timeout); mutex_enter(&iscsi_cleanup_mtx); - if (conn->c_timedout == TOUT_QUEUED) { + if (conn->c_timedout == TOUT_QUEUED) TAILQ_REMOVE(&iscsi_timeout_conn_list, conn, c_tchain); - conn->c_timedout = TOUT_NONE; - } if (curlwp != iscsi_cleanproc) { while (conn->c_timedout == TOUT_BUSY) kpause("connbusy", false, 1, &iscsi_cleanup_mtx); } + conn->c_timedout = TOUT_NONE; mutex_exit(&iscsi_cleanup_mtx); } @@ -1674,9 +1675,11 @@ ccb_timeout_co(void *par) ccb_t *ccb = par; mutex_enter(&iscsi_cleanup_mtx); - ccb->ccb_timedout = TOUT_QUEUED; - TAILQ_INSERT_TAIL(&iscsi_timeout_ccb_list, ccb, ccb_tchain); - iscsi_notify_cleanup(); + if (ccb->ccb_timedout == TOUT_ARMED) { + ccb->ccb_timedout = TOUT_QUEUED; + TAILQ_INSERT_TAIL(&iscsi_timeout_ccb_list, ccb, ccb_tchain); + iscsi_notify_cleanup(); + } mutex_exit(&iscsi_cleanup_mtx); } @@ -1696,14 +1699,13 @@ ccb_timeout_stop(ccb_t *ccb) { callout_stop(&ccb->ccb_timeout); mutex_enter(&iscsi_cleanup_mtx); - if (ccb->ccb_timedout == TOUT_QUEUED) { + if (ccb->ccb_timedout == TOUT_QUEUED) TAILQ_REMOVE(&iscsi_timeout_ccb_list, ccb, ccb_tchain); - ccb->ccb_timedout = TOUT_NONE; - } if (curlwp != iscsi_cleanproc) { while (ccb->ccb_timedout == TOUT_BUSY) kpause("ccbbusy", false, 1, &iscsi_cleanup_mtx); } + ccb->ccb_timedout = TOUT_NONE; mutex_exit(&iscsi_cleanup_mtx); } Index: src/sys/dev/iscsi/iscsi_send.c diff -u src/sys/dev/iscsi/iscsi_send.c:1.40 src/sys/dev/iscsi/iscsi_send.c:1.41 --- src/sys/dev/iscsi/iscsi_send.c:1.40 Sat Nov 25 10:08:27 2023 +++ src/sys/dev/iscsi/iscsi_send.c Sat Aug 24 09:39:44 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: iscsi_send.c,v 1.40 2023/11/25 10:08:27 mlelstv Exp $ */ +/* $NetBSD: iscsi_send.c,v 1.41 2024/08/24 09:39:44 mlelstv Exp $ */ /*- * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc. @@ -1723,19 +1723,19 @@ ccb_timeout(ccb_t *ccb) { connection_t *conn = ccb->ccb_connection; + if (conn == NULL) { + /* XXX Should never happen */ + printf("ccb_timeout: num=%d total=%d disp=%d invalid ccb=%p\n", + ccb->ccb_num_timeouts+1, ccb->ccb_total_tries, + ccb->ccb_disp, ccb); + return; + } + ccb->ccb_total_tries++; DEBC(conn, 0, ("ccb_timeout: num=%d total=%d disp=%d\n", ccb->ccb_num_timeouts+1, ccb->ccb_total_tries, ccb->ccb_disp)); - /* - * XXX can we time out after connection is closed ? - */ - if (conn == NULL) { - wake_ccb(ccb, ISCSI_STATUS_TIMEOUT); - return; - } - if (++ccb->ccb_num_timeouts > MAX_CCB_TIMEOUTS || ccb->ccb_total_tries > MAX_CCB_TRIES || ccb->ccb_disp <= CCBDISP_FREE ||