git: 2de803570472 - stable/13 - Add freebsd32 compat shims for SIOC[GS]DRVSPEC.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 10 Nov 2022 19:15:14 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=2de8035704728d2749705b58866a4eb3f4a5e02d

commit 2de8035704728d2749705b58866a4eb3f4a5e02d
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2021-05-05 20:58:50 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-11-10 18:25:58 +0000

    Add freebsd32 compat shims for SIOC[GS]DRVSPEC.
    
    Reviewed by:    brooks, kib
    Obtained from:  CheriBSD
    Sponsored by:   DARPA
    Differential Revision:  https://reviews.freebsd.org/D29892
    
    (cherry picked from commit d61d98f4ed68c5f6c81586a529057fe51fd50a60)
---
 sys/net/if.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/sys/net/if.c b/sys/net/if.c
index 2389969fefd5..eefa0ac93291 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -148,6 +148,15 @@ CTASSERT(sizeof(struct ifreq) == sizeof(struct ifreq32));
 CTASSERT(__offsetof(struct ifreq, ifr_ifru) ==
     __offsetof(struct ifreq32, ifr_ifru));
 
+struct ifdrv32 {
+	char		ifd_name[IFNAMSIZ];
+	uint32_t	ifd_cmd;
+	uint32_t	ifd_len;
+	uint32_t	ifd_data;
+};
+#define SIOCSDRVSPEC32	_IOC_NEWTYPE(SIOCSDRVSPEC, struct ifdrv32)
+#define SIOCGDRVSPEC32	_IOC_NEWTYPE(SIOCGDRVSPEC, struct ifdrv32)
+
 struct ifgroupreq32 {
 	char	ifgr_name[IFNAMSIZ];
 	u_int	ifgr_len;
@@ -2947,11 +2956,13 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
 #ifdef COMPAT_FREEBSD32
 	union {
 		struct ifconf ifc;
+		struct ifdrv ifd;
 		struct ifmediareq ifmr;
 	} thunk;
 	caddr_t saved_data;
 	u_long saved_cmd;
 	struct ifconf32 *ifc32;
+	struct ifdrv32 *ifd32;
 	struct ifmediareq32 *ifmr32;
 #endif
 	struct ifnet *ifp;
@@ -2983,6 +2994,17 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
 		data = (caddr_t)&thunk.ifc;
 		cmd = SIOCGIFCONF;
 		break;
+	case SIOCGDRVSPEC32:
+	case SIOCSDRVSPEC32:
+		ifd32 = (struct ifdrv32 *)data;
+		memcpy(thunk.ifd.ifd_name, ifd32->ifd_name,
+		    sizeof(thunk.ifd.ifd_name));
+		thunk.ifd.ifd_cmd = ifd32->ifd_cmd;
+		thunk.ifd.ifd_len = ifd32->ifd_len;
+		thunk.ifd.ifd_data = PTRIN(ifd32->ifd_data);
+		data = (caddr_t)&thunk.ifd;
+		cmd = _IOC_NEWTYPE(cmd, struct ifdrv);
+		break;
 	case SIOCGIFMEDIA32:
 	case SIOCGIFXMEDIA32:
 		ifmr32 = (struct ifmediareq32 *)data;
@@ -3103,6 +3125,17 @@ out_noref:
 	case SIOCGIFCONF32:
 		ifc32->ifc_len = thunk.ifc.ifc_len;
 		break;
+	case SIOCGDRVSPEC32:
+		/*
+		 * SIOCGDRVSPEC is IOWR, but nothing actually touches
+		 * the struct so just assert that ifd_len (the only
+		 * field it might make sense to update) hasn't
+		 * changed.
+		 */
+		KASSERT(thunk.ifd.ifd_len == ifd32->ifd_len,
+		    ("ifd_len was updated %u -> %zu", ifd32->ifd_len,
+			thunk.ifd.ifd_len));
+		break;
 	case SIOCGIFMEDIA32:
 	case SIOCGIFXMEDIA32:
 		ifmr32->ifm_current = thunk.ifmr.ifm_current;