From owner-dev-commits-src-branches@freebsd.org Mon Sep 27 00:54:05 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 8091B6AB9BE; Mon, 27 Sep 2021 00:54:05 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HHkfj30qPz3NyG; Mon, 27 Sep 2021 00:54:05 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 47742276DB; Mon, 27 Sep 2021 00:54:05 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 18R0s5o4028006; Mon, 27 Sep 2021 00:54:05 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 18R0s5cn028005; Mon, 27 Sep 2021 00:54:05 GMT (envelope-from git) Date: Mon, 27 Sep 2021 00:54:05 GMT Message-Id: <202109270054.18R0s5cn028005@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Alexander Motin Subject: git: 964d2210e122 - stable/13 - Fix data race in scsi cd driver. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mav X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 964d2210e122edd74b9da601bcf4e36721926055 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Sep 2021 00:54:05 -0000 The branch stable/13 has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=964d2210e122edd74b9da601bcf4e36721926055 commit 964d2210e122edd74b9da601bcf4e36721926055 Author: Alexander Motin AuthorDate: 2021-09-13 12:59:51 +0000 Commit: Alexander Motin CommitDate: 2021-09-27 00:54:02 +0000 Fix data race in scsi cd driver. There is a data race between cdsysctlinit and cdcheckmedia. Both functions change softc->flags without synchronization. Submitted by: Arseny Smalyuk MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D31726 (cherry picked from commit e76786909ce0195855196305a04d86b40f138894) --- sys/cam/scsi/scsi_cd.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index da367ad65c5d..ee59da3e53c9 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -372,6 +372,7 @@ cdoninvalidate(struct cam_periph *periph) { struct cd_softc *softc; + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; /* @@ -452,7 +453,7 @@ cdasync(void *callback_arg, u_int32_t code, printf("cdasync: Unable to attach new device " "due to status 0x%x\n", status); - break; + return; } case AC_UNIT_ATTENTION: { @@ -472,10 +473,10 @@ cdasync(void *callback_arg, u_int32_t code, if (asc == 0x28 && ascq == 0x00) disk_media_changed(softc->disk, M_NOWAIT); } - cam_periph_async(periph, code, path, arg); break; } case AC_SCSI_AEN: + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; if (softc->state == CD_STATE_NORMAL && !softc->tur) { if (cam_periph_acquire(periph) == 0) { @@ -489,6 +490,7 @@ cdasync(void *callback_arg, u_int32_t code, { struct ccb_hdr *ccbh; + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; /* * Don't fail on the expected unit attention @@ -497,12 +499,13 @@ cdasync(void *callback_arg, u_int32_t code, softc->flags |= CD_FLAG_RETRY_UA; LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) ccbh->ccb_state |= CD_CCB_RETRY_UA; - /* FALLTHROUGH */ + break; } default: - cam_periph_async(periph, code, path, arg); break; } + + cam_periph_async(periph, code, path, arg); } static void @@ -521,7 +524,9 @@ cdsysctlinit(void *context, int pending) snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); sysctl_ctx_init(&softc->sysctl_ctx); + cam_periph_lock(periph); softc->flags |= CD_FLAG_SCTX_INIT; + cam_periph_unlock(periph); softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_kern_cam_cd), OID_AUTO, tmpstr2, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, tmpstr, @@ -900,6 +905,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) struct bio *bp; struct ccb_scsiio *csio; + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdstart\n")); @@ -1144,6 +1150,7 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cddone\n")); + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; csio = &done_ccb->csio; @@ -2624,6 +2631,7 @@ cdprevent(struct cam_periph *periph, int action) CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdprevent\n")); + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; if (((action == PR_ALLOW) @@ -2661,6 +2669,7 @@ cdmediaprobedone(struct cam_periph *periph) { struct cd_softc *softc; + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; softc->flags &= ~CD_FLAG_MEDIA_SCAN_ACT; @@ -2682,6 +2691,7 @@ cdcheckmedia(struct cam_periph *periph, int do_wait) struct cd_softc *softc; int error; + cam_periph_assert(periph, MA_OWNED); softc = (struct cd_softc *)periph->softc; error = 0; @@ -3071,13 +3081,14 @@ cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct cd_softc *)periph->softc; - error = 0; + cam_periph_assert(periph, MA_OWNED); /* * We use a status of CAM_REQ_INVALID as shorthand -- if a 6 byte * CDB comes back with this particular error, try transforming it * into the 10 byte version. */ + error = 0; if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) { error = cd6byteworkaround(ccb); } else if (scsi_extract_sense_ccb(ccb,