git: 04cd74b4cdb1 - main - IPv4 multicast: fix netstat -g

From: Mike Karels <karels_at_FreeBSD.org>
Date: Tue, 22 Mar 2022 12:41:15 UTC
The branch main has been updated by karels:

URL: https://cgit.FreeBSD.org/src/commit/?id=04cd74b4cdb1203bc0fbfb85d8490a5b45eadf64

commit 04cd74b4cdb1203bc0fbfb85d8490a5b45eadf64
Author:     Mike Karels <karels@FreeBSD.org>
AuthorDate: 2022-03-21 19:59:13 +0000
Commit:     Mike Karels <karels@FreeBSD.org>
CommitDate: 2022-03-22 12:38:01 +0000

    IPv4 multicast: fix netstat -g
    
    The vif structure includes fields at the end which are #ifdef KERNEL,
    causing a mismatch between the structure sizes between kernel and
    user level.  netstat -g failed with an ENOMEM on the sysctl to fetch
    the vif table.  Change the vif sysctl code in ip_mroute to copy out
    only the user-level-visible portion of each table entry.
    
    Reviewed by:    bz, wma
    Differential Revision: https://reviews.freebsd.org/D34627
---
 sys/netinet/ip_mroute.c | 11 ++++++++---
 sys/netinet/ip_mroute.h |  1 +
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index e6acfd4dcfc7..cc356e3678f3 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -2727,18 +2727,23 @@ static SYSCTL_NODE(_net_inet_ip, OID_AUTO, mfctable,
 static int
 sysctl_viflist(SYSCTL_HANDLER_ARGS)
 {
-	int error;
+	int error, i;
 
 	if (req->newptr)
 		return (EPERM);
 	if (V_viftable == NULL)		/* XXX unlocked */
 		return (0);
-	error = sysctl_wire_old_buffer(req, sizeof(*V_viftable) * MAXVIFS);
+	error = sysctl_wire_old_buffer(req, MROUTE_VIF_SYSCTL_LEN * MAXVIFS);
 	if (error)
 		return (error);
 
 	MRW_RLOCK();
-	error = SYSCTL_OUT(req, V_viftable, sizeof(*V_viftable) * MAXVIFS);
+	/* Copy out user-visible portion of vif entry. */
+	for (i = 0; i < MAXVIFS; i++) {
+		error = SYSCTL_OUT(req, &V_viftable[i], MROUTE_VIF_SYSCTL_LEN);
+		if (error)
+			break;
+	}
 	MRW_RUNLOCK();
 	return (error);
 }
diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h
index 5ad25b485dfc..aaf87770001e 100644
--- a/sys/netinet/ip_mroute.h
+++ b/sys/netinet/ip_mroute.h
@@ -265,6 +265,7 @@ struct vif {
     u_long		v_bytes_in;	/* # bytes in on interface	     */
     u_long		v_bytes_out;	/* # bytes out on interface	     */
 #ifdef _KERNEL
+#define	MROUTE_VIF_SYSCTL_LEN	__offsetof(struct vif, v_spin)
     struct mtx		v_spin;		/* Spin mutex for pkt stats          */
     char		v_spin_name[32];
 #endif