Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Jul 2018 13:13:49 +0000 (UTC)
From:      Brooks Davis <brooks@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335979 - in head: . lib/libkvm sys/kern sys/netinet sys/sys usr.bin/netstat usr.bin/sockstat
Message-ID:  <201807051313.w65DDnQJ041281@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: brooks
Date: Thu Jul  5 13:13:48 2018
New Revision: 335979
URL: https://svnweb.freebsd.org/changeset/base/335979

Log:
  Make struct xinpcb and friends word-size independent.
  
  Replace size_t members with ksize_t (uint64_t) and pointer members
  (never used as pointers in userspace, but instead as unique
  idenitifiers) with kvaddr_t (uint64_t). This makes the structs
  identical between 32-bit and 64-bit ABIs.
  
  On 64-bit bit systems, the ABI is maintained. On 32-bit systems,
  this is an ABI breaking change. The ABI of most of these structs
  was previously broken in r315662.  This also imposes a small API
  change on userspace consumers who must handle kernel pointers
  becoming virtual addresses.
  
  PR:		228301 (exp-run by antoine)
  Reviewed by:	jtl, kib, rwatson (various versions)
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D15386

Modified:
  head/UPDATING
  head/lib/libkvm/kvm.h
  head/sys/kern/kern_descrip.c
  head/sys/kern/uipc_socket.c
  head/sys/kern/uipc_usrreq.c
  head/sys/netinet/in_pcb.c
  head/sys/netinet/in_pcb.h
  head/sys/netinet/sctp_sysctl.c
  head/sys/netinet/sctp_uio.h
  head/sys/netinet/tcp_var.h
  head/sys/sys/file.h
  head/sys/sys/param.h
  head/sys/sys/socketvar.h
  head/sys/sys/types.h
  head/sys/sys/unpcb.h
  head/usr.bin/netstat/inet.c
  head/usr.bin/netstat/unix.c
  head/usr.bin/sockstat/sockstat.c

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/UPDATING	Thu Jul  5 13:13:48 2018	(r335979)
@@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
 	disable the most expensive debugging functionality run
 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
 
+20180705:
+	The ABI of syscalls used by management tools like sockstat and
+	netstat has been broken to allow 32-bit binaries to work on
+	64-bit kernels without modification.  These programs will need
+	to match the kernel in order to function.  External programs may
+	require minor modifications to accommodate a change of type in
+	structures from pointers to 64-bit virtual addresses.
+
 20180702:
 	On i386 and amd64 atomics are now inlined. Out of tree modules using
 	atomics will need to be rebuilt.

Modified: head/lib/libkvm/kvm.h
==============================================================================
--- head/lib/libkvm/kvm.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/lib/libkvm/kvm.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -61,8 +61,6 @@ typedef	__ssize_t	ssize_t;
 #define	_SSIZE_T_DECLARED
 #endif
 
-typedef	uint64_t kvaddr_t;		/* An address in a target image. */
-
 struct kvm_nlist {
 	const char *n_name;
 	unsigned char n_type;

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/kern/kern_descrip.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -3362,10 +3362,10 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
 			if ((fp = fdp->fd_ofiles[n].fde_file) == NULL)
 				continue;
 			xf.xf_fd = n;
-			xf.xf_file = fp;
-			xf.xf_data = fp->f_data;
-			xf.xf_vnode = fp->f_vnode;
-			xf.xf_type = fp->f_type;
+			xf.xf_file = (kvaddr_t)fp;
+			xf.xf_data = (kvaddr_t)fp->f_data;
+			xf.xf_vnode = (kvaddr_t)fp->f_vnode;
+			xf.xf_type = (kvaddr_t)fp->f_type;
 			xf.xf_count = fp->f_count;
 			xf.xf_msgcount = 0;
 			xf.xf_offset = foffset_get(fp);

Modified: head/sys/kern/uipc_socket.c
==============================================================================
--- head/sys/kern/uipc_socket.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/kern/uipc_socket.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -3985,12 +3985,12 @@ sotoxsocket(struct socket *so, struct xsocket *xso)
 {
 
 	xso->xso_len = sizeof *xso;
-	xso->xso_so = so;
+	xso->xso_so = (kvaddr_t)so;
 	xso->so_type = so->so_type;
 	xso->so_options = so->so_options;
 	xso->so_linger = so->so_linger;
 	xso->so_state = so->so_state;
-	xso->so_pcb = so->so_pcb;
+	xso->so_pcb = (kvaddr_t)so->so_pcb;
 	xso->xso_protocol = so->so_proto->pr_protocol;
 	xso->xso_family = so->so_proto->pr_domain->dom_family;
 	xso->so_timeo = so->so_timeo;

Modified: head/sys/kern/uipc_usrreq.c
==============================================================================
--- head/sys/kern/uipc_usrreq.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/kern/uipc_usrreq.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -1853,7 +1853,7 @@ unp_pcblist(SYSCTL_HANDLER_ARGS)
 
 		if (freeunp == 0 && unp->unp_gencnt <= gencnt) {
 			xu->xu_len = sizeof *xu;
-			xu->xu_unpp = unp;
+			xu->xu_unpp = (kvaddr_t)unp;
 			/*
 			 * XXX - need more locking here to protect against
 			 * connect/disconnect races for SMP.
@@ -1870,10 +1870,10 @@ unp_pcblist(SYSCTL_HANDLER_ARGS)
 				      unp->unp_conn->unp_addr->sun_len);
 			else
 				bzero(&xu->xu_caddr, sizeof(xu->xu_caddr));
-			xu->unp_vnode = unp->unp_vnode;
-			xu->unp_conn = unp->unp_conn;
-			xu->xu_firstref = LIST_FIRST(&unp->unp_refs);
-			xu->xu_nextref = LIST_NEXT(unp, unp_reflink);
+			xu->unp_vnode = (kvaddr_t)unp->unp_vnode;
+			xu->unp_conn = (kvaddr_t)unp->unp_conn;
+			xu->xu_firstref = (kvaddr_t)LIST_FIRST(&unp->unp_refs);
+			xu->xu_nextref = (kvaddr_t)LIST_NEXT(unp, unp_reflink);
 			xu->unp_gencnt = unp->unp_gencnt;
 			sotoxsocket(unp->unp_socket, &xu->xu_socket);
 			UNP_PCB_UNLOCK(unp);

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/netinet/in_pcb.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -2906,7 +2906,7 @@ in_pcbtoxinpcb(const struct inpcb *inp, struct xinpcb 
 		bzero(&xi->xi_socket, sizeof(struct xsocket));
 	bcopy(&inp->inp_inc, &xi->inp_inc, sizeof(struct in_conninfo));
 	xi->inp_gencnt = inp->inp_gencnt;
-	xi->inp_ppcb = inp->inp_ppcb;
+	xi->inp_ppcb = (kvaddr_t)inp->inp_ppcb;
 	xi->inp_flow = inp->inp_flow;
 	xi->inp_flowid = inp->inp_flowid;
 	xi->inp_flowtype = inp->inp_flowtype;

Modified: head/sys/netinet/in_pcb.h
==============================================================================
--- head/sys/netinet/in_pcb.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/netinet/in_pcb.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -366,12 +366,12 @@ struct inpcb {
  */
 #ifdef _SYS_SOCKETVAR_H_
 struct xinpcb {
-	size_t		xi_len;		/* length of this structure */
+	ksize_t		xi_len;			/* length of this structure */
 	struct xsocket	xi_socket;		/* (s,p) */
 	struct in_conninfo inp_inc;		/* (s,p) */
 	uint64_t	inp_gencnt;		/* (s,p) */
 	union {
-		void	*inp_ppcb;		/* (s) netstat(1) */
+		kvaddr_t inp_ppcb;		/* (s) netstat(1) */
 		int64_t	ph_ppcb;
 	};
 	int64_t		inp_spare64[4];
@@ -394,10 +394,12 @@ struct xinpcb {
 } __aligned(8);
 
 struct xinpgen {
-	size_t		xig_len;	/* length of this structure */
+	ksize_t	xig_len;	/* length of this structure */
 	u_int		xig_count;	/* number of PCBs at this time */
+	uint32_t	_xig_spare32;
 	inp_gen_t	xig_gen;	/* generation count at this time */
 	so_gen_t	xig_sogen;	/* socket generation count this time */
+	uint64_t	_xig_spare64[4];
 } __aligned(8);
 #ifdef	_KERNEL
 void	in_pcbtoxinpcb(const struct inpcb *, struct xinpcb *);

Modified: head/sys/netinet/sctp_sysctl.c
==============================================================================
--- head/sys/netinet/sctp_sysctl.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/netinet/sctp_sysctl.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -409,7 +409,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
 		xinpcb.total_recvs = inp->total_recvs;
 		xinpcb.total_nospaces = inp->total_nospaces;
 		xinpcb.fragmentation_point = inp->sctp_frag_point;
-		xinpcb.socket = inp->sctp_socket;
+		xinpcb.socket = (kvaddr_t)inp->sctp_socket;
 		so = inp->sctp_socket;
 		if ((so == NULL) ||
 		    (!SCTP_IS_LISTENING(inp)) ||

Modified: head/sys/netinet/sctp_uio.h
==============================================================================
--- head/sys/netinet/sctp_uio.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/netinet/sctp_uio.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -1175,14 +1175,11 @@ struct xsctp_inpcb {
 	uint16_t local_port;
 	uint16_t qlen_old;
 	uint16_t maxqlen_old;
-	void *socket;
+	uint16_t __spare16;
+	kvaddr_t socket;
 	uint32_t qlen;
 	uint32_t maxqlen;
-#if defined(__LP64__)
-	uint32_t extra_padding[27];	/* future */
-#else
-	uint32_t extra_padding[28];	/* future */
-#endif
+	uint32_t extra_padding[26];	/* future */
 };
 
 struct xsctp_tcb {

Modified: head/sys/netinet/tcp_var.h
==============================================================================
--- head/sys/netinet/tcp_var.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/netinet/tcp_var.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -677,7 +677,7 @@ void hhook_run_tcp_est_out(struct tcpcb *tp,
  */
 #if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_)
 struct xtcpcb {
-	size_t		xt_len;		/* length of this structure */
+	ksize_t	xt_len;		/* length of this structure */
 	struct xinpcb	xt_inp;
 	char		xt_stack[TCP_FUNCTION_NAME_LEN_MAX];	/* (s) */
 	char		xt_logid[TCP_LOG_ID_LEN];	/* (s) */

Modified: head/sys/sys/file.h
==============================================================================
--- head/sys/sys/file.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/sys/file.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -209,18 +209,23 @@ struct file {
  * Userland version of struct file, for sysctl
  */
 struct xfile {
-	size_t	xf_size;	/* size of struct xfile */
+	ksize_t	xf_size;	/* size of struct xfile */
 	pid_t	xf_pid;		/* owning process */
 	uid_t	xf_uid;		/* effective uid of owning process */
 	int	xf_fd;		/* descriptor number */
-	void	*xf_file;	/* address of struct file */
+	int	_xf_int_pad1;
+	kvaddr_t xf_file;	/* address of struct file */
 	short	xf_type;	/* descriptor type */
+	short	_xf_short_pad1;
 	int	xf_count;	/* reference count */
 	int	xf_msgcount;	/* references from message queue */
+	int	_xf_int_pad2;
 	off_t	xf_offset;	/* file offset */
-	void	*xf_data;	/* file descriptor specific data */
-	void	*xf_vnode;	/* vnode pointer */
+	kvaddr_t xf_data;	/* file descriptor specific data */
+	kvaddr_t xf_vnode;	/* vnode pointer */
 	u_int	xf_flag;	/* flags (see fcntl.h) */
+	int	_xf_int_pad3;
+	int64_t	_xf_int64_pad[6];
 };
 
 #ifdef _KERNEL

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/sys/param.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -60,7 +60,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1200071	/* Master, propagated to newvers */
+#define __FreeBSD_version 1200072	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

Modified: head/sys/sys/socketvar.h
==============================================================================
--- head/sys/sys/socketvar.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/sys/socketvar.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -474,13 +474,13 @@ int	accept_filt_generic_mod_event(module_t mod, int ev
  * Structure to export socket from kernel to utilities, via sysctl(3).
  */
 struct xsocket {
-	size_t		xso_len;	/* length of this structure */
+	ksize_t		xso_len;	/* length of this structure */
 	union {
-		void	*xso_so;	/* kernel address of struct socket */
+		kvaddr_t xso_so;	/* kernel address of struct socket */
 		int64_t ph_so;
 	};
 	union {
-		void 	*so_pcb;	/* kernel address of struct inpcb */
+		kvaddr_t so_pcb;	/* kernel address of struct inpcb */
 		int64_t ph_pcb;
 	};
 	uint64_t	so_oobmark;

Modified: head/sys/sys/types.h
==============================================================================
--- head/sys/sys/types.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/sys/types.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -251,6 +251,15 @@ struct cap_rights;
 typedef	struct cap_rights	cap_rights_t;
 #endif
 
+/*
+ * Types suitable for exporting size and pointers (as virtual addresses)
+ * from the kernel independent of native word size.  These should be
+ * used in place of size_t and (u)intptr_t in structs which contain such
+ * types that are shared with userspace.
+ */
+typedef	__uint64_t	kvaddr_t;
+typedef	__uint64_t	ksize_t;
+
 typedef	__vm_offset_t	vm_offset_t;
 typedef	__int64_t	vm_ooffset_t;
 typedef	__vm_paddr_t	vm_paddr_t;

Modified: head/sys/sys/unpcb.h
==============================================================================
--- head/sys/sys/unpcb.h	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/sys/sys/unpcb.h	Thu Jul  5 13:13:48 2018	(r335979)
@@ -138,12 +138,12 @@ struct unpcb {
  */
 #ifdef	_SYS_SOCKETVAR_H_
 struct xunpcb {
-	size_t		xu_len;			/* length of this structure */
-	void		*xu_unpp;		/* to help netstat, fstat */
-	void		*unp_vnode;		/* (s) */
-	void		*unp_conn;		/* (s) */
-	void		*xu_firstref;		/* (s) */
-	void		*xu_nextref;		/* (s) */
+	ksize_t		xu_len;			/* length of this structure */
+	kvaddr_t	xu_unpp;		/* to help netstat, fstat */
+	kvaddr_t	unp_vnode;		/* (s) */
+	kvaddr_t	unp_conn;		/* (s) */
+	kvaddr_t	xu_firstref;		/* (s) */
+	kvaddr_t	xu_nextref;		/* (s) */
 	unp_gen_t	unp_gencnt;		/* (s) */
 	int64_t		xu_spare64[8];
 	int32_t		xu_spare32[8];
@@ -159,7 +159,7 @@ struct xunpcb {
 } __aligned(8);
 
 struct xunpgen {
-	size_t	xug_len;
+	ksize_t	xug_len;
 	u_int	xug_count;
 	unp_gen_t xug_gen;
 	so_gen_t xug_sogen;

Modified: head/usr.bin/netstat/inet.c
==============================================================================
--- head/usr.bin/netstat/inet.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/usr.bin/netstat/inet.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -159,12 +159,12 @@ sotoxsocket(struct socket *so, struct xsocket *xso)
 
 	bzero(xso, sizeof *xso);
 	xso->xso_len = sizeof *xso;
-	xso->xso_so = so;
+	xso->xso_so = (kvaddr_t)so;
 	xso->so_type = so->so_type;
 	xso->so_options = so->so_options;
 	xso->so_linger = so->so_linger;
 	xso->so_state = so->so_state;
-	xso->so_pcb = so->so_pcb;
+	xso->so_pcb = (kvaddr_t)so->so_pcb;
 	if (kread((uintptr_t)so->so_proto, &proto, sizeof(proto)) != 0)
 		return (-1);
 	xso->xso_protocol = proto.pr_protocol;

Modified: head/usr.bin/netstat/unix.c
==============================================================================
--- head/usr.bin/netstat/unix.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/usr.bin/netstat/unix.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -153,7 +153,7 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_lon
 	xu.xu_len = sizeof xu;
 	KREAD(head_off, &head, sizeof(head));
 	LIST_FOREACH(unp, &head, unp_link) {
-		xu.xu_unpp = unp;
+		xu.xu_unpp = (kvaddr_t)unp;
 		KREAD(unp, &unp0, sizeof (*unp));
 		unp = &unp0;
 

Modified: head/usr.bin/sockstat/sockstat.c
==============================================================================
--- head/usr.bin/sockstat/sockstat.c	Thu Jul  5 11:50:59 2018	(r335978)
+++ head/usr.bin/sockstat/sockstat.c	Thu Jul  5 13:13:48 2018	(r335979)
@@ -108,8 +108,8 @@ struct addr {
 };
 
 struct sock {
-	void *socket;
-	void *pcb;
+	kvaddr_t socket;
+	kvaddr_t pcb;
 	int shown;
 	int vflag;
 	int family;
@@ -789,8 +789,8 @@ gather_unix(int proto)
 			warnx("struct xunpcb size mismatch");
 			goto out;
 		}
-		if ((xup->unp_conn == NULL && !opt_l) ||
-		    (xup->unp_conn != NULL && !opt_c))
+		if ((xup->unp_conn == 0 && !opt_l) ||
+		    (xup->unp_conn != 0 && !opt_c))
 			continue;
 		if ((sock = calloc(1, sizeof(*sock))) == NULL)
 			err(1, "malloc()");
@@ -806,8 +806,8 @@ gather_unix(int proto)
 		if (xup->xu_addr.sun_family == AF_UNIX)
 			laddr->address =
 			    *(struct sockaddr_storage *)(void *)&xup->xu_addr;
-		else if (xup->unp_conn != NULL)
-			*(void **)&(faddr->address) = xup->unp_conn;
+		else if (xup->unp_conn != 0)
+			*(kvaddr_t*)&(faddr->address) = xup->unp_conn;
 		laddr->next = NULL;
 		faddr->next = NULL;
 		sock->laddr = laddr;
@@ -1008,7 +1008,7 @@ sctp_path_state(int state)
 static void
 displaysock(struct sock *s, int pos)
 {
-	void *p;
+	kvaddr_t p;
 	int hash, first, offset;
 	struct addr *laddr, *faddr;
 	struct sock *s_tmp;
@@ -1054,8 +1054,8 @@ displaysock(struct sock *s, int pos)
 				break;
 			}
 			/* client */
-			p = *(void **)&(faddr->address);
-			if (p == NULL) {
+			p = *(kvaddr_t*)&(faddr->address);
+			if (p == 0) {
 				pos += xprintf("(not connected)");
 				offset += opt_w ? 92 : 44;
 				break;
@@ -1174,13 +1174,13 @@ display(void)
 	}
 	setpassent(1);
 	for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
-		if (xf->xf_data == NULL)
+		if (xf->xf_data == 0)
 			continue;
 		if (opt_j >= 0 && opt_j != getprocjid(xf->xf_pid))
 			continue;
 		hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
 		for (s = sockhash[hash]; s != NULL; s = s->next) {
-			if ((void *)s->socket != xf->xf_data)
+			if (s->socket != xf->xf_data)
 				continue;
 			if (!check_ports(s))
 				continue;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807051313.w65DDnQJ041281>