Module Name:    src
Committed By:   msaitoh
Date:           Mon May  9 17:13:30 UTC 2022

Modified Files:
        src/sys/dev/ic: mfi.c

Log Message:
Use union mbox instead of unit8_t[] to avoid unaligned access.

 - Same as other OSes.
 - mfii.c already use this.
 - Found by kUBSan.


To generate a diff of this commit:
cvs rdiff -u -r1.73 -r1.74 src/sys/dev/ic/mfi.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/ic/mfi.c
diff -u src/sys/dev/ic/mfi.c:1.73 src/sys/dev/ic/mfi.c:1.74
--- src/sys/dev/ic/mfi.c:1.73	Mon May  9 15:56:36 2022
+++ src/sys/dev/ic/mfi.c	Mon May  9 17:13:30 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: mfi.c,v 1.73 2022/05/09 15:56:36 msaitoh Exp $ */
+/* $NetBSD: mfi.c,v 1.74 2022/05/09 17:13:30 msaitoh Exp $ */
 /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */
 
 /*
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.73 2022/05/09 15:56:36 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.74 2022/05/09 17:13:30 msaitoh Exp $");
 
 #include "bio.h"
 
@@ -156,9 +156,11 @@ static int		mfi_scsi_ld_io(struct mfi_cc
 static void		mfi_scsi_ld_done(struct mfi_ccb *);
 static void		mfi_scsi_xs_done(struct mfi_ccb *, int, int);
 static int		mfi_mgmt_internal(struct mfi_softc *, uint32_t,
-			    uint32_t, uint32_t, void *, uint8_t *, bool);
+			    uint32_t, uint32_t, void *, const union mfi_mbox *,
+			    bool);
 static int		mfi_mgmt(struct mfi_ccb *,struct scsipi_xfer *,
-			    uint32_t, uint32_t, uint32_t, void *, uint8_t *);
+			    uint32_t, uint32_t, uint32_t, void *,
+			    const union mfi_mbox *);
 static void		mfi_mgmt_done(struct mfi_ccb *);
 
 #if NBIO > 0
@@ -967,22 +969,22 @@ static bool
 mfi_shutdown(device_t dev, int how)
 {
 	struct mfi_softc	*sc = device_private(dev);
-	uint8_t			mbox[MFI_MBOX_SIZE];
+	union mfi_mbox		mbox;
 	int s = splbio();
 
 	DNPRINTF(MFI_D_MISC, "%s: mfi_shutdown\n", DEVNAME(sc));
 	if (sc->sc_running) {
-		memset(mbox, 0, sizeof(mbox));
-		mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
+		memset(&mbox, 0, sizeof(mbox));
+		mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
 		if (mfi_mgmt_internal(sc, MR_DCMD_CTRL_CACHE_FLUSH,
-		    MFI_DATA_NONE, 0, NULL, mbox, true)) {
+		    MFI_DATA_NONE, 0, NULL, &mbox, true)) {
 			aprint_error_dev(dev, "shutdown: cache flush failed\n");
 			goto fail;
 		}
 
-		mbox[0] = 0;
+		mbox.b[0] = 0;
 		if (mfi_mgmt_internal(sc, MR_DCMD_CTRL_SHUTDOWN,
-		    MFI_DATA_NONE, 0, NULL, mbox, true)) {
+		    MFI_DATA_NONE, 0, NULL, &mbox, true)) {
 			aprint_error_dev(dev, "shutdown: "
 			    "firmware shutdown failed\n");
 			goto fail;
@@ -1579,10 +1581,10 @@ mfi_scsipi_request(struct scsipi_channel
 	struct scsipi_rw_10	*rwb;
 	struct scsipi_rw_12	*rw12;
 	struct scsipi_rw_16	*rw16;
+	union mfi_mbox		mbox;
 	uint64_t		blockno;
 	uint32_t		blockcnt;
 	uint8_t			target;
-	uint8_t			mbox[MFI_MBOX_SIZE];
 	int			s;
 
 	switch (req) {
@@ -1684,10 +1686,10 @@ mfi_scsipi_request(struct scsipi_channel
 
 	case SCSI_SYNCHRONIZE_CACHE_10:
 	case SCSI_SYNCHRONIZE_CACHE_16:
-		memset(mbox, 0, sizeof(mbox));
-		mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
+		memset(&mbox, 0, sizeof(mbox));
+		mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
 		if (mfi_mgmt(ccb, xs,
-		    MR_DCMD_CTRL_CACHE_FLUSH, MFI_DATA_NONE, 0, NULL, mbox)) {
+		    MR_DCMD_CTRL_CACHE_FLUSH, MFI_DATA_NONE, 0, NULL, &mbox)) {
 			goto stuffup;
 		}
 		break;
@@ -1839,7 +1841,7 @@ mfi_create_sgl(struct mfi_ccb *ccb, int 
 
 static int
 mfi_mgmt_internal(struct mfi_softc *sc, uint32_t opc, uint32_t dir,
-    uint32_t len, void *buf, uint8_t *mbox, bool poll)
+    uint32_t len, void *buf, const union mfi_mbox *mbox, bool poll)
 {
 	struct mfi_ccb		*ccb;
 	int			rv = 1;
@@ -1873,8 +1875,8 @@ done:
 }
 
 static int
-mfi_mgmt(struct mfi_ccb *ccb, struct scsipi_xfer *xs,
-    uint32_t opc, uint32_t dir, uint32_t len, void *buf, uint8_t *mbox)
+mfi_mgmt(struct mfi_ccb *ccb, struct scsipi_xfer *xs, uint32_t opc,
+    uint32_t dir, uint32_t len, void *buf, const union mfi_mbox *mbox)
 {
 	struct mfi_dcmd_frame	*dcmd;
 
@@ -2037,7 +2039,7 @@ static int
 mfi_ioctl_vol(struct mfi_softc *sc, struct bioc_vol *bv)
 {
 	int			i, per, rv = EINVAL;
-	uint8_t			mbox[MFI_MBOX_SIZE];
+	union mfi_mbox		mbox;
 
 	DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol %#x\n",
 	    DEVNAME(sc), bv->bv_volid);
@@ -2047,13 +2049,13 @@ mfi_ioctl_vol(struct mfi_softc *sc, stru
 		goto done;
 
 	i = bv->bv_volid;
-	memset(mbox, 0, sizeof(mbox));
-	mbox[0] = sc->sc_ld_list.mll_list[i].mll_ld.mld_target;
+	memset(&mbox, 0, sizeof(mbox));
+	mbox.b[0] = sc->sc_ld_list.mll_list[i].mll_ld.mld_target;
 	DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol target %#x\n",
-	    DEVNAME(sc), mbox[0]);
+	    DEVNAME(sc), mbox.b[0]);
 
 	if (mfi_mgmt_internal(sc, MR_DCMD_LD_GET_INFO, MFI_DATA_IN,
-	    sizeof(sc->sc_ld_details), &sc->sc_ld_details, mbox, false))
+	    sizeof(sc->sc_ld_details), &sc->sc_ld_details, &mbox, false))
 		goto done;
 
 	if (bv->bv_volid >= sc->sc_ld_list.mll_no_ld) {
@@ -2142,7 +2144,7 @@ mfi_ioctl_disk(struct mfi_softc *sc, str
 	int			i, rv = EINVAL;
 	int			arr, vol, disk;
 	uint32_t		size;
-	uint8_t			mbox[MFI_MBOX_SIZE];
+	union mfi_mbox		mbox;
 
 	DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_disk %#x\n",
 	    DEVNAME(sc), bd->bd_diskid);
@@ -2222,11 +2224,11 @@ mfi_ioctl_disk(struct mfi_softc *sc, str
 	}
 
 	/* get the remaining fields */
-	memset(mbox, 0, sizeof(mbox));
-	*((uint16_t *)&mbox) = ar[arr].pd[disk].mar_pd.mfp_id;
+	memset(&mbox, 0, sizeof(mbox));
+	mbox.s[0] = ar[arr].pd[disk].mar_pd.mfp_id;
 	memset(pd, 0, sizeof(*pd));
 	if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN,
-	    sizeof *pd, pd, mbox, false))
+	    sizeof *pd, pd, &mbox, false))
 		goto freeme;
 
 	bd->bd_size = pd->mpd_size * 512; /* bytes per block */
@@ -2300,7 +2302,7 @@ static int
 mfi_ioctl_blink(struct mfi_softc *sc, struct bioc_blink *bb)
 {
 	int			i, found, rv = EINVAL;
-	uint8_t			mbox[MFI_MBOX_SIZE];
+	union mfi_mbox		mbox;
 	uint32_t		cmd;
 	struct mfi_pd_list	*pd;
 
@@ -2327,9 +2329,8 @@ mfi_ioctl_blink(struct mfi_softc *sc, st
 	if (!found)
 		goto done;
 
-	memset(mbox, 0, sizeof mbox);
-
-	*((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id;
+	memset(&mbox, 0, sizeof(mbox));
+	mbox.s[0] = pd->mpl_address[i].mpa_pd_id;
 
 	switch (bb->bb_status) {
 	case BIOC_SBUNBLINK:
@@ -2348,7 +2349,7 @@ mfi_ioctl_blink(struct mfi_softc *sc, st
 	}
 
 
-	if (mfi_mgmt_internal(sc, cmd, MFI_DATA_NONE, 0, NULL, mbox, false))
+	if (mfi_mgmt_internal(sc, cmd, MFI_DATA_NONE, 0, NULL, &mbox, false))
 		goto done;
 
 	rv = 0;
@@ -2362,7 +2363,7 @@ mfi_ioctl_setstate(struct mfi_softc *sc,
 {
 	struct mfi_pd_list	*pd;
 	int			i, found, rv = EINVAL;
-	uint8_t			mbox[MFI_MBOX_SIZE];
+	union mfi_mbox		mbox;
 
 	DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_setstate %x\n", DEVNAME(sc),
 	    bs->bs_status);
@@ -2383,21 +2384,20 @@ mfi_ioctl_setstate(struct mfi_softc *sc,
 	if (!found)
 		goto done;
 
-	memset(mbox, 0, sizeof mbox);
-
-	*((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id;
+	memset(&mbox, 0, sizeof(mbox));
+	mbox.s[0] = pd->mpl_address[i].mpa_pd_id;
 
 	switch (bs->bs_status) {
 	case BIOC_SSONLINE:
-		mbox[2] = MFI_PD_ONLINE;
+		mbox.b[4] = MFI_PD_ONLINE;
 		break;
 
 	case BIOC_SSOFFLINE:
-		mbox[2] = MFI_PD_OFFLINE;
+		mbox.b[4] = MFI_PD_OFFLINE;
 		break;
 
 	case BIOC_SSHOTSPARE:
-		mbox[2] = MFI_PD_HOTSPARE;
+		mbox.b[4] = MFI_PD_HOTSPARE;
 		break;
 /*
 	case BIOC_SSREBUILD:
@@ -2411,7 +2411,7 @@ mfi_ioctl_setstate(struct mfi_softc *sc,
 
 
 	if (mfi_mgmt_internal(sc, MR_DCMD_PD_SET_STATE, MFI_DATA_NONE,
-	    0, NULL, mbox, false))
+	    0, NULL, &mbox, false))
 		goto done;
 
 	rv = 0;
@@ -2432,7 +2432,7 @@ mfi_bio_hs(struct mfi_softc *sc, int vol
 	char			vend[8+16+4+1];
 	int			i, rv = EINVAL;
 	uint32_t		size;
-	uint8_t			mbox[MFI_MBOX_SIZE];
+	union mfi_mbox		mbox;
 
 	DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs %d\n", DEVNAME(sc), volid);
 
@@ -2476,10 +2476,10 @@ mfi_bio_hs(struct mfi_softc *sc, int vol
 	    cfg->mfc_no_hs, hs, cfg, hs[i].mhs_pd.mfp_id);
 
 	/* get pd fields */
-	memset(mbox, 0, sizeof mbox);
-	*((uint16_t *)&mbox) = hs[i].mhs_pd.mfp_id;
+	memset(&mbox, 0, sizeof(mbox));
+	mbox.s[0] = hs[i].mhs_pd.mfp_id;
 	if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN,
-	    sizeof *pd, pd, mbox, false)) {
+	    sizeof *pd, pd, &mbox, false)) {
 		DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs illegal PD\n",
 		    DEVNAME(sc));
 		goto freeme;
@@ -3389,7 +3389,7 @@ mfi_tbolt_sync_map_info(struct work *w, 
 	struct mfi_softc *sc = v;
 	int i;
 	struct mfi_ccb *ccb = NULL;
-	uint8_t mbox[MFI_MBOX_SIZE];
+	union mfi_mbox mbox;
 	struct mfi_ld *ld_sync;
 	size_t ld_size;
 	int s;
@@ -3426,11 +3426,11 @@ again:
 	}
 	sc->sc_ldsync_ccb = ccb;
 
-	memset(mbox, 0, MFI_MBOX_SIZE);
-	mbox[0] = sc->sc_ld_list.mll_no_ld;
-	mbox[1] = MFI_DCMD_MBOX_PEND_FLAG;
+	memset(&mbox, 0, sizeof(mbox));
+	mbox.b[0] = sc->sc_ld_list.mll_no_ld;
+	mbox.b[1] = MFI_DCMD_MBOX_PEND_FLAG;
 	if (mfi_mgmt(ccb, NULL, MR_DCMD_LD_MAP_GET_INFO, MFI_DATA_OUT,
-	    ld_size, ld_sync, mbox)) {
+	    ld_size, ld_sync, &mbox)) {
 		aprint_error_dev(sc->sc_dev, "Failed to create sync command\n");
 		goto err;
 	}

Reply via email to