changeset 20176:fccaa6b5aff6

13324 struct dk_minfo_ext size differences trigger SSP in libfdisk Reviewed by: Jason King <jason.brian.king@gmail.com> Reviewed by: Andy Fiddaman <andy@omniosce.org> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Joshua Clulow <josh@sysmgr.org>
author Robert Mustacchi <rm@fingolfin.org>
date Mon, 23 Nov 2020 14:09:18 -0800
parents eeb335867b32
children 4c8d447baf62
files usr/src/uts/common/fs/zfs/zvol.c usr/src/uts/common/io/blkdev/blkdev.c usr/src/uts/common/io/lofi.c usr/src/uts/common/io/scsi/targets/sd.c usr/src/uts/common/sys/dkio.h
diffstat 5 files changed, 61 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/zvol.c	Sat Nov 21 21:27:25 2020 +0200
+++ b/usr/src/uts/common/fs/zfs/zvol.c	Mon Nov 23 14:09:18 2020 -0800
@@ -1668,6 +1668,7 @@
 	case DKIOCGMEDIAINFOEXT:
 	{
 		struct dk_minfo_ext dkmext;
+		size_t len;
 
 		bzero(&dkmext, sizeof (dkmext));
 		dkmext.dki_lbsize = 1U << zv->zv_min_bs;
@@ -1675,7 +1676,17 @@
 		dkmext.dki_capacity = zv->zv_volsize >> zv->zv_min_bs;
 		dkmext.dki_media_type = DK_UNKNOWN;
 		mutex_exit(&zfsdev_state_lock);
-		if (ddi_copyout(&dkmext, (void *)arg, sizeof (dkmext), flag))
+
+		switch (ddi_model_convert_from(flag & FMODELS)) {
+		case DDI_MODEL_ILP32:
+			len = sizeof (struct dk_minfo_ext32);
+			break;
+		default:
+			len = sizeof (struct dk_minfo_ext);
+			break;
+		}
+
+		if (ddi_copyout(&dkmext, (void *)arg, len, flag))
 			error = SET_ERROR(EFAULT);
 		return (error);
 	}
--- a/usr/src/uts/common/io/blkdev/blkdev.c	Sat Nov 21 21:27:25 2020 +0200
+++ b/usr/src/uts/common/io/blkdev/blkdev.c	Mon Nov 23 14:09:18 2020 -0800
@@ -1510,6 +1510,7 @@
 	}
 	case DKIOCGMEDIAINFOEXT: {
 		struct dk_minfo_ext miext;
+		size_t len;
 
 		/* make sure our state information is current */
 		bd_update_state(bd);
@@ -1518,7 +1519,17 @@
 		miext.dki_lbsize = (1U << bd->d_blkshift);
 		miext.dki_pbsize = (1U << bd->d_pblkshift);
 		miext.dki_capacity = bd->d_numblks;
-		if (ddi_copyout(&miext, ptr, sizeof (miext), flag)) {
+
+		switch (ddi_model_convert_from(flag & FMODELS)) {
+		case DDI_MODEL_ILP32:
+			len = sizeof (struct dk_minfo_ext32);
+			break;
+		default:
+			len = sizeof (struct dk_minfo_ext);
+			break;
+		}
+
+		if (ddi_copyout(&miext, ptr, len, flag)) {
 			return (EFAULT);
 		}
 		return (0);
--- a/usr/src/uts/common/io/lofi.c	Sat Nov 21 21:27:25 2020 +0200
+++ b/usr/src/uts/common/io/lofi.c	Mon Nov 23 14:09:18 2020 -0800
@@ -3340,7 +3340,14 @@
 
 		if (cmd == DKIOCGMEDIAINFOEXT) {
 			media_info.dki_pbsize = 1U << lsp->ls_pbshift;
-			size = sizeof (struct dk_minfo_ext);
+			switch (ddi_model_convert_from(flag & FMODELS)) {
+			case DDI_MODEL_ILP32:
+				size = sizeof (struct dk_minfo_ext32);
+				break;
+			default:
+				size = sizeof (struct dk_minfo_ext);
+				break;
+			}
 		} else {
 			size = sizeof (struct dk_minfo);
 		}
--- a/usr/src/uts/common/io/scsi/targets/sd.c	Sat Nov 21 21:27:25 2020 +0200
+++ b/usr/src/uts/common/io/scsi/targets/sd.c	Mon Nov 23 14:09:18 2020 -0800
@@ -24013,13 +24013,24 @@
 {
 	struct dk_minfo_ext	mie;
 	int			rval = 0;
+	size_t			len;
 
 	rval = sd_get_media_info_com(dev, &mie.dki_media_type,
 	    &mie.dki_lbsize, &mie.dki_capacity, &mie.dki_pbsize);
 
 	if (rval)
 		return (rval);
-	if (ddi_copyout(&mie, arg, sizeof (struct dk_minfo_ext), flag))
+
+	switch (ddi_model_convert_from(flag & FMODELS)) {
+	case DDI_MODEL_ILP32:
+		len = sizeof (struct dk_minfo_ext32);
+		break;
+	default:
+		len = sizeof (struct dk_minfo_ext);
+		break;
+	}
+
+	if (ddi_copyout(&mie, arg, len, flag))
 		rval = EFAULT;
 	return (rval);
 
--- a/usr/src/uts/common/sys/dkio.h	Sat Nov 21 21:27:25 2020 +0200
+++ b/usr/src/uts/common/sys/dkio.h	Mon Nov 23 14:09:18 2020 -0800
@@ -356,6 +356,23 @@
 	uint_t		dki_pbsize;	/* Physical blocksize of media */
 };
 
+#ifdef	_KERNEL
+
+/*
+ * The 32-bit version of the media info API did not end up with a consistent
+ * size in an ILP32 and LP64 interface. While the actual offsets of the members
+ * are the same, the resulting structure size is not.
+ */
+#pragma pack(4)
+struct dk_minfo_ext32 {
+	uint_t		dki_media_type;	/* Media type or profile info */
+	uint_t		dki_lbsize;	/* Logical blocksize of media */
+	diskaddr_t	dki_capacity;	/* Capacity as # of dki_lbsize blks */
+	uint_t		dki_pbsize;	/* Physical blocksize of media */
+};
+#pragma pack()
+#endif
+
 /*
  * Media types or profiles known
  */