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>