tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

patch: sockaddr instead of mbuf to carry addresses



hi,

attached is the first of a set of patches intended to remove the use of mbuf as a bucket to carry sockaddr structures for per-user requests. this patch introduces the structure required and changes bind.

i've been running it myself, the atf tests work with it and there has been some private review prior to posting.

comments welcome

Index: sys/compat/linux/common/linux_socket.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_socket.c,v
retrieving revision 1.122
diff -u -p -r1.122 linux_socket.c
--- sys/compat/linux/common/linux_socket.c	26 Nov 2014 09:53:53 -0000	1.122
+++ sys/compat/linux/common/linux_socket.c	14 Mar 2015 14:47:37 -0000
@@ -121,6 +121,8 @@ int linux_getifconf(struct lwp *, regist
 int linux_getifhwaddr(struct lwp *, register_t *, u_int, void *);
 static int linux_get_sa(struct lwp *, int, struct mbuf **,
 		const struct osockaddr *, unsigned int);
+static int linux_get_sa_sb(struct lwp *, int, struct sockaddr_big *,
+		const struct osockaddr *, socklen_t);
 static int linux_sa_put(struct osockaddr *osa);
 static int linux_to_bsd_msg_flags(int);
 static int bsd_to_linux_msg_flags(int);
@@ -1445,14 +1447,14 @@ linux_sys_bind(struct lwp *l, const stru
 		syscallarg(int) namelen;
 	} */
 	int		error;
-	struct mbuf     *nam;
+	struct sockaddr_big sb;
 
-	error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, name),
+	error = linux_get_sa_sb(l, SCARG(uap, s), &sb, SCARG(uap, name),
 	    SCARG(uap, namelen));
 	if (error)
 		return (error);
 
-	return do_sys_bind(l, SCARG(uap, s), nam);
+	return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb);
 }
 
 int
@@ -1493,6 +1495,77 @@ linux_sys_getpeername(struct lwp *l, con
 	return (0);
 }
 
+static int
+linux_get_sa_sb(struct lwp *l, int s, struct sockaddr_big *sb,
+    const struct osockaddr *name, socklen_t namelen)
+{
+	int error, bdom;
+
+	if (namelen > UCHAR_MAX ||
+	    namelen <= offsetof(struct sockaddr_big, sb_data))
+		return EINVAL;
+
+	error = copyin(name, sb, namelen);
+	if (error)
+		return error;
+
+	bdom = linux_to_bsd_domain(sb->sb_family);
+	if (bdom == -1)
+		return EINVAL;
+
+	/*
+	 * If the family is unspecified, use address family of the socket.
+	 * This avoid triggering strict family checks in netinet/in_pcb.c et.al.
+	 */
+	if (bdom == AF_UNSPEC) {
+		struct socket *so;
+
+		/* fd_getsock() will use the descriptor for us */
+		if ((error = fd_getsock(s, &so)) != 0)
+			return error;
+
+		bdom = so->so_proto->pr_domain->dom_family;
+		fd_putfile(s);
+	}
+
+	/*
+	 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
+	 * which lacks the scope id compared with RFC2553 one. If we detect
+	 * the situation, reject the address and write a message to system log.
+	 *
+	 * Still accept addresses for which the scope id is not used.
+	 */
+	if (bdom == AF_INET6 &&
+	    namelen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) {
+		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sb;
+		if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) &&
+		    (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
+		     IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) ||
+		     IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) ||
+		     IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
+		     IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
+			struct proc *p = l->l_proc;
+			int uid = l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1;
+
+			log(LOG_DEBUG,
+			    "pid %d (%s), uid %d: obsolete pre-RFC2553 "
+			    "sockaddr_in6 rejected",
+			    p->p_pid, p->p_comm, uid);
+			return EINVAL;
+		}
+		namelen = sizeof(struct sockaddr_in6);
+		sin6->sin6_scope_id = 0;
+	}
+
+	if (bdom == AF_INET)
+		namelen = sizeof(struct sockaddr_in);
+
+	sb->sb_family = bdom;
+	sb->sb_len = namelen;
+	ktrkuser("mbsoname", sb, namelen);
+	return 0;
+}
+
 /*
  * Copy the osockaddr structure pointed to by osa to mbuf, adjust
  * family and convert to sockaddr.
Index: sys/compat/svr4/svr4_stream.c
===================================================================
RCS file: /cvsroot/src/sys/compat/svr4/svr4_stream.c,v
retrieving revision 1.81
diff -u -p -r1.81 svr4_stream.c
--- sys/compat/svr4/svr4_stream.c	5 Sep 2014 09:21:55 -0000	1.81
+++ sys/compat/svr4/svr4_stream.c	14 Mar 2015 14:47:37 -0000
@@ -752,10 +752,10 @@ ti_bind(file_t *fp, int fd, struct svr4_
 	struct svr4_strm *st = svr4_stream_get(fp);
 	struct sockaddr_in sain;
 	struct sockaddr_un saun;
-	void *skp, *sup = NULL;
+	struct sockaddr_big *sbig;
+	void *sup = NULL;
 	int sasize;
 	struct svr4_strmcmd bnd;
-	struct mbuf *name;
 
 	if (st == NULL) {
 		DPRINTF(("ti_bind: bad file descriptor\n"));
@@ -775,8 +775,8 @@ ti_bind(file_t *fp, int fd, struct svr4_
 
 	switch (st->s_family) {
 	case AF_INET:
-		skp = &sain;
-		sasize = sizeof(sain);
+		sbig = (struct sockaddr_big *)&sain;
+		sbig->sb_len = sasize = sizeof(sain);
 
 		if (bnd.offs == 0)
 			goto reply;
@@ -789,8 +789,8 @@ ti_bind(file_t *fp, int fd, struct svr4_
 		break;
 
 	case AF_LOCAL:
-		skp = &saun;
-		sasize = sizeof(saun);
+		sbig = (struct sockaddr_big *)&saun;
+		sbig->sb_len = sasize = sizeof(saun);
 		if (bnd.offs == 0)
 			goto reply;
 
@@ -814,15 +814,9 @@ ti_bind(file_t *fp, int fd, struct svr4_
 		return ENOSYS;
 	}
 
-	name = m_get(M_WAIT, MT_SONAME);
-	if (sasize > MLEN)
-		MEXTMALLOC(name, sasize, M_WAITOK);
-
-	memcpy(mtod(name, void *), skp, sasize);
-
 	DPRINTF(("TI_BIND: fileno %d\n", fd));
 
-	error = do_sys_bind(l, fd, name);
+	error = do_sys_bind(l, fd, (struct sockaddr *)sbig);
 	if (error != 0) {
 		DPRINTF(("TI_BIND: bind failed %d\n", error));
 		return error;
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v
retrieving revision 1.235
diff -u -p -r1.235 uipc_socket.c
--- sys/kern/uipc_socket.c	5 Sep 2014 09:20:59 -0000	1.235
+++ sys/kern/uipc_socket.c	14 Mar 2015 14:47:38 -0000
@@ -624,7 +624,7 @@ sofamily(const struct socket *so)
 }
 
 int
-sobind(struct socket *so, struct mbuf *nam, struct lwp *l)
+sobind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	int	error;
 
Index: sys/kern/uipc_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.174
diff -u -p -r1.174 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c	6 Mar 2015 03:35:00 -0000	1.174
+++ sys/kern/uipc_syscalls.c	14 Mar 2015 14:47:38 -0000
@@ -91,6 +91,8 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_syscall
  */
 extern const struct fileops socketops;
 
+static int	sockargs_sb(struct sockaddr_big *, const void *, socklen_t);
+
 int
 sys___socket30(struct lwp *l, const struct sys___socket30_args *uap,
     register_t *retval)
@@ -118,30 +120,25 @@ sys_bind(struct lwp *l, const struct sys
 		syscallarg(const struct sockaddr *)	name;
 		syscallarg(unsigned int)		namelen;
 	} */
-	struct mbuf	*nam;
 	int		error;
+	struct sockaddr_big sb;
 
-	error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
-	    MT_SONAME);
+	error = sockargs_sb(&sb, SCARG(uap, name), SCARG(uap, namelen));
 	if (error)
 		return error;
 
-	return do_sys_bind(l, SCARG(uap, s), nam);
+	return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb);
 }
 
 int
-do_sys_bind(struct lwp *l, int fd, struct mbuf *nam)
+do_sys_bind(struct lwp *l, int fd, struct sockaddr *nam)
 {
 	struct socket	*so;
 	int		error;
 
-	if ((error = fd_getsock(fd, &so)) != 0) {
-		m_freem(nam);
-		return (error);
-	}
-	MCLAIM(nam, so->so_mowner);
+	if ((error = fd_getsock(fd, &so)) != 0)
+		return error;
 	error = sobind(so, nam, l);
-	m_freem(nam);
 	fd_putfile(fd);
 	return error;
 }
@@ -1444,6 +1441,37 @@ sys_getpeername(struct lwp *l, const str
 	return error;
 }
 
+static int
+sockargs_sb(struct sockaddr_big *sb, const void *name, socklen_t buflen)
+{
+	int error;
+
+	/*
+	 * We can't allow socket names > UCHAR_MAX in length, since that
+	 * will overflow sb_len. Further no reasonable buflen is <=
+	 * offsetof(sockaddr_big, sb_data) since it shall be at least
+	 * the size of the preamble sb_len and sb_family members.
+	 */
+	if (buflen > UCHAR_MAX ||
+	    buflen <= offsetof(struct sockaddr_big, sb_data))
+		return EINVAL;
+
+	error = copyin(name, (void *)sb, buflen);
+	if (error)
+		return error;
+
+#if BYTE_ORDER != BIG_ENDIAN
+	/*
+	 * 4.3BSD compat thing - need to stay, since bind(2),
+	 * connect(2), sendto(2) were not versioned for COMPAT_43.
+	 */
+	if (sb->sb_family == 0 && sb->sb_len < AF_MAX)
+		sb->sb_family = sb->sb_len;
+#endif
+	sb->sb_len = buflen;
+	return 0;
+}
+
 /*
  * XXX In a perfect world, we wouldn't pass around socket control
  * XXX arguments in mbufs, and this could go away.
Index: sys/kern/uipc_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.175
diff -u -p -r1.175 uipc_usrreq.c
--- sys/kern/uipc_usrreq.c	1 Mar 2015 01:14:41 -0000	1.175
+++ sys/kern/uipc_usrreq.c	14 Mar 2015 14:47:38 -0000
@@ -931,8 +931,24 @@ makeun(struct mbuf *nam, size_t *addrlen
 	return sun;
 }
 
+/*
+ * we only need to perform this allocation until syscalls other than
+ * bind are adjusted to use sockaddr_big.
+ */
+static struct sockaddr_un *
+makeun_sb(struct sockaddr *nam, size_t *addrlen)
+{
+	struct sockaddr_un *sun;
+
+	*addrlen = nam->sa_len + 1;
+	sun = malloc(*addrlen, M_SONAME, M_WAITOK);
+	memcpy(sun, nam, nam->sa_len);
+	*(((char *)sun) + nam->sa_len) = '\0';
+	return sun;
+}
+
 static int
-unp_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+unp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct sockaddr_un *sun;
 	struct unpcb *unp;
@@ -963,7 +979,7 @@ unp_bind(struct socket *so, struct mbuf 
 	sounlock(so);
 
 	p = l->l_proc;
-	sun = makeun(nam, &addrlen);
+	sun = makeun_sb(nam, &addrlen);
 
 	pb = pathbuf_create(sun->sun_path);
 	if (pb == NULL) {
Index: sys/net/if_gre.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_gre.c,v
retrieving revision 1.161
diff -u -p -r1.161 if_gre.c
--- sys/net/if_gre.c	5 Sep 2014 09:22:22 -0000	1.161
+++ sys/net/if_gre.c	14 Mar 2015 14:47:38 -0000
@@ -444,7 +444,7 @@ gre_socreate(struct gre_softc *sc, const
 	sockaddr_copy(sa, MIN(MLEN, sizeof(sp->sp_src)), sstocsa(&sp->sp_src));
 	m->m_len = sp->sp_src.ss_len;
 
-	if ((rc = sobind(so, m, curlwp)) != 0) {
+	if ((rc = sobind(so, sa, curlwp)) != 0) {
 		GRE_DPRINTF(sc, "sobind failed\n");
 		goto out;
 	}
Index: sys/net/link_proto.c
===================================================================
RCS file: /cvsroot/src/sys/net/link_proto.c,v
retrieving revision 1.24
diff -u -p -r1.24 link_proto.c
--- sys/net/link_proto.c	9 Aug 2014 05:33:01 -0000	1.24
+++ sys/net/link_proto.c	14 Mar 2015 14:47:38 -0000
@@ -51,7 +51,7 @@ static int sockaddr_dl_cmp(const struct 
 static int link_attach(struct socket *, int);
 static void link_detach(struct socket *);
 static int link_accept(struct socket *, struct mbuf *);
-static int link_bind(struct socket *, struct mbuf *, struct lwp *);
+static int link_bind(struct socket *, struct sockaddr *, struct lwp *);
 static int link_listen(struct socket *, struct lwp *);
 static int link_connect(struct socket *, struct mbuf *, struct lwp *);
 static int link_connect2(struct socket *, struct socket *);
@@ -274,7 +274,7 @@ link_accept(struct socket *so, struct mb
 }
 
 static int
-link_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+link_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	KASSERT(solocked(so));
 
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvsroot/src/sys/net/rtsock.c,v
retrieving revision 1.166
diff -u -p -r1.166 rtsock.c
--- sys/net/rtsock.c	2 Dec 2014 21:28:31 -0000	1.166
+++ sys/net/rtsock.c	14 Mar 2015 14:47:38 -0000
@@ -239,7 +239,7 @@ COMPATNAME(route_accept)(struct socket *
 }
 
 static int
-COMPATNAME(route_bind)(struct socket *so, struct mbuf *nam, struct lwp *l)
+COMPATNAME(route_bind)(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	KASSERT(solocked(so));
 
Index: sys/netatalk/ddp_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netatalk/ddp_usrreq.c,v
retrieving revision 1.63
diff -u -p -r1.63 ddp_usrreq.c
--- sys/netatalk/ddp_usrreq.c	9 Aug 2014 05:33:01 -0000	1.63
+++ sys/netatalk/ddp_usrreq.c	14 Mar 2015 14:47:38 -0000
@@ -58,7 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c
 
 static void at_pcbdisconnect(struct ddpcb *);
 static void at_sockaddr(struct ddpcb *, struct mbuf *);
-static int at_pcbsetaddr(struct ddpcb *, struct mbuf *);
+static int at_pcbsetaddr(struct ddpcb *, struct sockaddr_at *);
 static int at_pcbconnect(struct ddpcb *, struct mbuf *);
 static void ddp_detach(struct socket *);
 
@@ -142,19 +142,16 @@ at_sockaddr(struct ddpcb *ddp, struct mb
 }
 
 static int
-at_pcbsetaddr(struct ddpcb *ddp, struct mbuf *addr)
+at_pcbsetaddr(struct ddpcb *ddp, struct sockaddr_at *sat)
 {
-	struct sockaddr_at lsat, *sat;
+	struct sockaddr_at lsat;
 	struct at_ifaddr *aa;
 	struct ddpcb   *ddpp;
 
 	if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT) {	/* shouldn't be bound */
 		return (EINVAL);
 	}
-	if (addr != 0) {	/* validate passed address */
-		sat = mtod(addr, struct sockaddr_at *);
-		if (addr->m_len != sizeof(*sat))
-			return (EINVAL);
+	if (NULL != sat) {	/* validate passed address */
 
 		if (sat->sat_family != AF_APPLETALK)
 			return (EAFNOSUPPORT);
@@ -413,12 +410,12 @@ ddp_accept(struct socket *so, struct mbu
 }
 
 static int
-ddp_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+ddp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	KASSERT(solocked(so));
 	KASSERT(sotoddpcb(so) != NULL);
 
-	return at_pcbsetaddr(sotoddpcb(so), nam);
+	return at_pcbsetaddr(sotoddpcb(so), (struct sockaddr_at *)nam);
 }
 
 static int
Index: sys/netbt/hci_socket.c
===================================================================
RCS file: /cvsroot/src/sys/netbt/hci_socket.c,v
retrieving revision 1.40
diff -u -p -r1.40 hci_socket.c
--- sys/netbt/hci_socket.c	9 Aug 2014 05:33:01 -0000	1.40
+++ sys/netbt/hci_socket.c	14 Mar 2015 14:47:38 -0000
@@ -492,16 +492,15 @@ hci_accept(struct socket *so, struct mbu
 }
 
 static int
-hci_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+hci_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct hci_pcb *pcb = so->so_pcb;
-	struct sockaddr_bt *sa;
+	struct sockaddr_bt *sa = (struct sockaddr_bt *)nam;
 
 	KASSERT(solocked(so));
 	KASSERT(pcb != NULL);
 	KASSERT(nam != NULL);
 
-	sa = mtod(nam, struct sockaddr_bt *);
 	if (sa->bt_len != sizeof(struct sockaddr_bt))
 		return EINVAL;
 
Index: sys/netbt/l2cap_socket.c
===================================================================
RCS file: /cvsroot/src/sys/netbt/l2cap_socket.c,v
retrieving revision 1.31
diff -u -p -r1.31 l2cap_socket.c
--- sys/netbt/l2cap_socket.c	9 Aug 2014 05:33:01 -0000	1.31
+++ sys/netbt/l2cap_socket.c	14 Mar 2015 14:47:38 -0000
@@ -134,10 +134,10 @@ l2cap_accept(struct socket *so, struct m
 }
 
 static int
-l2cap_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+l2cap_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct l2cap_channel *pcb = so->so_pcb;
-	struct sockaddr_bt *sa;
+	struct sockaddr_bt *sa = (struct sockaddr_bt *)nam;
 
 	KASSERT(solocked(so));
 	KASSERT(nam != NULL);
@@ -145,7 +145,6 @@ l2cap_bind(struct socket *so, struct mbu
 	if (pcb == NULL)
 		return EINVAL;
 
-	sa = mtod(nam, struct sockaddr_bt *);
 	if (sa->bt_len != sizeof(struct sockaddr_bt))
 		return EINVAL;
 
Index: sys/netbt/rfcomm_socket.c
===================================================================
RCS file: /cvsroot/src/sys/netbt/rfcomm_socket.c,v
retrieving revision 1.33
diff -u -p -r1.33 rfcomm_socket.c
--- sys/netbt/rfcomm_socket.c	9 Aug 2014 05:33:01 -0000	1.33
+++ sys/netbt/rfcomm_socket.c	14 Mar 2015 14:47:38 -0000
@@ -142,10 +142,10 @@ rfcomm_accept(struct socket *so, struct 
 }
 
 static int
-rfcomm_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+rfcomm_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct rfcomm_dlc *pcb = so->so_pcb;
-	struct sockaddr_bt *sa;
+	struct sockaddr_bt *sa = (struct sockaddr_bt *)nam;
 
 	KASSERT(solocked(so));
 	KASSERT(nam != NULL);
@@ -153,7 +153,6 @@ rfcomm_bind(struct socket *so, struct mb
 	if (pcb == NULL)
 		return EINVAL;
 
-	sa = mtod(nam, struct sockaddr_bt *);
 	if (sa->bt_len != sizeof(struct sockaddr_bt))
 		return EINVAL;
 
Index: sys/netbt/sco_socket.c
===================================================================
RCS file: /cvsroot/src/sys/netbt/sco_socket.c,v
retrieving revision 1.33
diff -u -p -r1.33 sco_socket.c
--- sys/netbt/sco_socket.c	9 Aug 2014 05:33:01 -0000	1.33
+++ sys/netbt/sco_socket.c	14 Mar 2015 14:47:38 -0000
@@ -125,10 +125,10 @@ sco_accept(struct socket *so, struct mbu
 }
 
 static int
-sco_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+sco_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct sco_pcb *pcb = so->so_pcb;
-	struct sockaddr_bt *sa;
+	struct sockaddr_bt *sa = (struct sockaddr_bt *)nam;
 
 	KASSERT(solocked(so));
 	KASSERT(nam != NULL);
@@ -136,7 +136,6 @@ sco_bind(struct socket *so, struct mbuf 
 	if (pcb == NULL)
 		return EINVAL;
 
-	sa = mtod(nam, struct sockaddr_bt *);
 	if (sa->bt_len != sizeof(struct sockaddr_bt))
 		return EINVAL;
 
Index: sys/netinet/in_pcb.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_pcb.c,v
retrieving revision 1.155
diff -u -p -r1.155 in_pcb.c
--- sys/netinet/in_pcb.c	25 Nov 2014 19:09:13 -0000	1.155
+++ sys/netinet/in_pcb.c	14 Mar 2015 14:47:38 -0000
@@ -401,10 +401,9 @@ in_pcbbind_port(struct inpcb *inp, struc
 }
 
 int
-in_pcbbind(void *v, struct mbuf *nam, struct lwp *l)
+in_pcbbind(void *v, struct sockaddr_in *sin, struct lwp *l)
 {
 	struct inpcb *inp = v;
-	struct sockaddr_in *sin = NULL; /* XXXGCC */
 	struct sockaddr_in lsin;
 	int error;
 
@@ -416,9 +415,8 @@ in_pcbbind(void *v, struct mbuf *nam, st
 	if (inp->inp_lport || !in_nullhost(inp->inp_laddr))
 		return (EINVAL);
 
-	if (nam != NULL) {
-		sin = mtod(nam, struct sockaddr_in *);
-		if (nam->m_len != sizeof (*sin))
+	if (NULL != sin) {
+		if (sin->sin_len != sizeof(*sin))
 			return (EINVAL);
 	} else {
 		lsin = *((const struct sockaddr_in *)
Index: sys/netinet/in_pcb.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_pcb.h,v
retrieving revision 1.55
diff -u -p -r1.55 in_pcb.h
--- sys/netinet/in_pcb.h	25 Nov 2014 15:04:37 -0000	1.55
+++ sys/netinet/in_pcb.h	14 Mar 2015 14:47:38 -0000
@@ -131,7 +131,7 @@ struct inpcb {
 #ifdef _KERNEL
 void	in_losing(struct inpcb *);
 int	in_pcballoc(struct socket *, void *);
-int	in_pcbbind(void *, struct mbuf *, struct lwp *);
+int	in_pcbbind(void *, struct sockaddr_in *, struct lwp *);
 int	in_pcbconnect(void *, struct mbuf *, struct lwp *);
 void	in_pcbdetach(void *);
 void	in_pcbdisconnect(void *);
Index: sys/netinet/raw_ip.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/raw_ip.c,v
retrieving revision 1.146
diff -u -p -r1.146 raw_ip.c
--- sys/netinet/raw_ip.c	10 Nov 2014 18:52:51 -0000	1.146
+++ sys/netinet/raw_ip.c	14 Mar 2015 14:47:38 -0000
@@ -557,10 +557,10 @@ rip_accept(struct socket *so, struct mbu
 }
 
 static int
-rip_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+rip_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct inpcb *inp = sotoinpcb(so);
-	struct sockaddr_in *addr;
+	struct sockaddr_in *addr = (struct sockaddr_in *)nam;
 	int error = 0;
 	int s;
 
@@ -568,12 +568,10 @@ rip_bind(struct socket *so, struct mbuf 
 	KASSERT(inp != NULL);
 	KASSERT(nam != NULL);
 
+	if (addr->sin_len != sizeof(*addr))
+		return EINVAL;
+
 	s = splsoftnet();
-	addr = mtod(nam, struct sockaddr_in *);
-	if (nam->m_len != sizeof(*addr)) {
-		error = EINVAL;
-		goto release;
-	}
 	if (IFNET_EMPTY()) {
 		error = EADDRNOTAVAIL;
 		goto release;
Index: sys/netinet/tcp_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.203
diff -u -p -r1.203 tcp_usrreq.c
--- sys/netinet/tcp_usrreq.c	14 Feb 2015 12:57:53 -0000	1.203
+++ sys/netinet/tcp_usrreq.c	14 Mar 2015 14:47:38 -0000
@@ -712,10 +712,14 @@ tcp_accept(struct socket *so, struct mbu
 }
 
 static int
-tcp_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+tcp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct inpcb *inp = NULL;
 	struct in6pcb *in6p = NULL;
+	struct sockaddr_in *sin = (struct sockaddr_in *)nam;
+#ifdef INET6
+	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
+#endif /* INET6 */
 	struct tcpcb *tp = NULL;
 	int s;
 	int error = 0;
@@ -733,12 +737,12 @@ tcp_bind(struct socket *so, struct mbuf 
 	switch (so->so_proto->pr_domain->dom_family) {
 #ifdef INET
 	case PF_INET:
-		error = in_pcbbind(inp, nam, l);
+		error = in_pcbbind(inp, sin, l);
 		break;
 #endif
 #ifdef INET6
 	case PF_INET6:
-		error = in6_pcbbind(in6p, nam, l);
+		error = in6_pcbbind(in6p, sin6, l);
 		if (!error) {
 			/* mapped addr case */
 			if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr))
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.217
diff -u -p -r1.217 udp_usrreq.c
--- sys/netinet/udp_usrreq.c	9 Aug 2014 05:33:01 -0000	1.217
+++ sys/netinet/udp_usrreq.c	14 Mar 2015 14:47:38 -0000
@@ -905,9 +905,10 @@ udp_accept(struct socket *so, struct mbu
 }
 
 static int
-udp_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+udp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct inpcb *inp = sotoinpcb(so);
+	struct sockaddr_in *sin = (struct sockaddr_in *)nam;
 	int error = 0;
 	int s;
 
@@ -916,7 +917,7 @@ udp_bind(struct socket *so, struct mbuf 
 	KASSERT(nam != NULL);
 
 	s = splsoftnet();
-	error = in_pcbbind(inp, nam, l);
+	error = in_pcbbind(inp, sin, l);
 	splx(s);
 
 	return error;
Index: sys/netinet6/in6_pcb.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.134
diff -u -p -r1.134 in6_pcb.c
--- sys/netinet6/in6_pcb.c	25 Nov 2014 19:09:13 -0000	1.134
+++ sys/netinet6/in6_pcb.c	14 Mar 2015 14:47:38 -0000
@@ -364,11 +364,10 @@ in6_pcbbind_port(struct in6pcb *in6p, st
 }
 
 int
-in6_pcbbind(void *v, struct mbuf *nam, struct lwp *l)
+in6_pcbbind(void *v, struct sockaddr_in6 *sin6, struct lwp *l)
 {
 	struct in6pcb *in6p = v;
 	struct sockaddr_in6 lsin6;
-	struct sockaddr_in6 *sin6 = NULL;
 	int error;
 
 	if (in6p->in6p_af != AF_INET6)
@@ -383,10 +382,9 @@ in6_pcbbind(void *v, struct mbuf *nam, s
 	      in6p->in6p_laddr.s6_addr32[3] == 0)))
 		return (EINVAL);
 
-	if (nam != NULL) {
+	if (NULL != sin6) {
 		/* We were provided a sockaddr_in6 to use. */
-		sin6 = mtod(nam, struct sockaddr_in6 *);
-		if (nam->m_len != sizeof(*sin6))
+		if (sin6->sin6_len != sizeof(*sin6))
 			return (EINVAL);
 	} else {
 		/* We always bind to *something*, even if it's "anything". */
Index: sys/netinet6/in6_pcb.h
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_pcb.h,v
retrieving revision 1.40
diff -u -p -r1.40 in6_pcb.h
--- sys/netinet6/in6_pcb.h	11 Oct 2014 20:53:16 -0000	1.40
+++ sys/netinet6/in6_pcb.h	14 Mar 2015 14:47:38 -0000
@@ -155,7 +155,7 @@ struct	in6pcb {
 void	in6_losing(struct in6pcb *);
 void	in6_pcbinit(struct inpcbtable *, int, int);
 int	in6_pcballoc(struct socket *, void *);
-int	in6_pcbbind(void *, struct mbuf *, struct lwp *);
+int	in6_pcbbind(void *, struct sockaddr_in6 *, struct lwp *);
 int	in6_pcbconnect(void *, struct mbuf *, struct lwp *);
 void	in6_pcbdetach(struct in6pcb *);
 void	in6_pcbdisconnect(struct in6pcb *);
Index: sys/netinet6/raw_ip6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.136
diff -u -p -r1.136 raw_ip6.c
--- sys/netinet6/raw_ip6.c	9 Aug 2014 05:33:01 -0000	1.136
+++ sys/netinet6/raw_ip6.c	14 Mar 2015 14:47:38 -0000
@@ -653,10 +653,10 @@ rip6_accept(struct socket *so, struct mb
 }
 
 static int
-rip6_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+rip6_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct in6pcb *in6p = sotoin6pcb(so);
-	struct sockaddr_in6 *addr;
+	struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
 	struct ifaddr *ia = NULL;
 	int error = 0;
 
@@ -664,8 +664,7 @@ rip6_bind(struct socket *so, struct mbuf
 	KASSERT(in6p != NULL);
 	KASSERT(nam != NULL);
 
-	addr = mtod(nam, struct sockaddr_in6 *);
-	if (nam->m_len != sizeof(*addr))
+	if (addr->sin6_len != sizeof(*addr))
 		return EINVAL;
 	if (IFNET_EMPTY() || addr->sin6_family != AF_INET6)
 		return EADDRNOTAVAIL;
Index: sys/netinet6/udp6_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.115
diff -u -p -r1.115 udp6_usrreq.c
--- sys/netinet6/udp6_usrreq.c	9 Aug 2014 05:33:01 -0000	1.115
+++ sys/netinet6/udp6_usrreq.c	14 Mar 2015 14:47:38 -0000
@@ -686,9 +686,10 @@ udp6_accept(struct socket *so, struct mb
 }
 
 static int
-udp6_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+udp6_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	struct in6pcb *in6p = sotoin6pcb(so);
+	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
 	int error = 0;
 	int s;
 
@@ -696,7 +697,7 @@ udp6_bind(struct socket *so, struct mbuf
 	KASSERT(in6p != NULL);
 
 	s = splsoftnet();
-	error = in6_pcbbind(in6p, nam, l);
+	error = in6_pcbbind(in6p, sin6, l);
 	splx(s);
 	return error;
 }
Index: sys/netipsec/keysock.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/keysock.c,v
retrieving revision 1.43
diff -u -p -r1.43 keysock.c
--- sys/netipsec/keysock.c	9 Aug 2014 05:33:01 -0000	1.43
+++ sys/netipsec/keysock.c	14 Mar 2015 14:47:38 -0000
@@ -495,7 +495,7 @@ key_accept(struct socket *so, struct mbu
 }
 
 static int
-key_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+key_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	KASSERT(solocked(so));
 
Index: sys/netmpls/mpls_proto.c
===================================================================
RCS file: /cvsroot/src/sys/netmpls/mpls_proto.c,v
retrieving revision 1.24
diff -u -p -r1.24 mpls_proto.c
--- sys/netmpls/mpls_proto.c	9 Aug 2014 05:33:01 -0000	1.24
+++ sys/netmpls/mpls_proto.c	14 Mar 2015 14:47:38 -0000
@@ -103,7 +103,7 @@ mpls_accept(struct socket *so, struct mb
 }
 
 static int
-mpls_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+mpls_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	KASSERT(solocked(so));
 
Index: sys/netnatm/natm.c
===================================================================
RCS file: /cvsroot/src/sys/netnatm/natm.c,v
retrieving revision 1.45
diff -u -p -r1.45 natm.c
--- sys/netnatm/natm.c	9 Aug 2014 05:33:01 -0000	1.45
+++ sys/netnatm/natm.c	14 Mar 2015 14:47:38 -0000
@@ -106,7 +106,7 @@ natm_accept(struct socket *so, struct mb
 }
 
 static int
-natm_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+natm_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	KASSERT(solocked(so));
 
Index: sys/nfs/nfs_boot.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_boot.c,v
retrieving revision 1.81
diff -u -p -r1.81 nfs_boot.c
--- sys/nfs/nfs_boot.c	25 Oct 2013 20:46:29 -0000	1.81
+++ sys/nfs/nfs_boot.c	14 Mar 2015 14:47:38 -0000
@@ -404,18 +404,14 @@ nfs_boot_enbroadcast(struct socket *so)
 int
 nfs_boot_sobind_ipport(struct socket *so, uint16_t port, struct lwp *l)
 {
-	struct mbuf *m;
-	struct sockaddr_in *sin;
+	struct sockaddr_in sin;
 	int error;
 
-	m = m_getclr(M_WAIT, MT_SONAME);
-	sin = mtod(m, struct sockaddr_in *);
-	sin->sin_len = m->m_len = sizeof(*sin);
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = INADDR_ANY;
-	sin->sin_port = htons(port);
-	error = sobind(so, m, l);
-	m_freem(m);
+	sin.sin_len = sizeof(sin);
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = INADDR_ANY;
+	sin.sin_port = htons(port);
+	error = sobind(so, (struct sockaddr *)&sin, l);
 	return (error);
 }
 
Index: sys/nfs/nfs_socket.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_socket.c,v
retrieving revision 1.193
diff -u -p -r1.193 nfs_socket.c
--- sys/nfs/nfs_socket.c	5 Sep 2014 05:34:57 -0000	1.193
+++ sys/nfs/nfs_socket.c	14 Mar 2015 14:47:38 -0000
@@ -182,9 +182,8 @@ nfs_connect(struct nfsmount *nmp, struct
 	struct socket *so;
 	int error, rcvreserve, sndreserve;
 	struct sockaddr *saddr;
-	struct sockaddr_in *sin;
-	struct sockaddr_in6 *sin6;
-	struct mbuf *m;
+	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
 	int val;
 
 	nmp->nm_so = NULL;
@@ -210,15 +209,11 @@ nfs_connect(struct nfsmount *nmp, struct
 		if ((error = so_setsockopt(NULL, so, IPPROTO_IP, IP_PORTRANGE,
 		    &val, sizeof(val))))
 			goto bad;
-		m = m_get(M_WAIT, MT_SONAME);
-		MCLAIM(m, so->so_mowner);
-		sin = mtod(m, struct sockaddr_in *);
-		sin->sin_len = m->m_len = sizeof (struct sockaddr_in);
-		sin->sin_family = AF_INET;
-		sin->sin_addr.s_addr = INADDR_ANY;
-		sin->sin_port = 0;
-		error = sobind(so, m, &lwp0);
-		m_freem(m);
+		sin.sin_len = sizeof(struct sockaddr_in);
+		sin.sin_family = AF_INET;
+		sin.sin_addr.s_addr = INADDR_ANY;
+		sin.sin_port = 0;
+		error = sobind(so, (struct sockaddr *)&sin, &lwp0);
 		if (error)
 			goto bad;
 	}
@@ -228,14 +223,10 @@ nfs_connect(struct nfsmount *nmp, struct
 		if ((error = so_setsockopt(NULL, so, IPPROTO_IPV6,
 		    IPV6_PORTRANGE, &val, sizeof(val))))
 			goto bad;
-		m = m_get(M_WAIT, MT_SONAME);
-		MCLAIM(m, so->so_mowner);
-		sin6 = mtod(m, struct sockaddr_in6 *);
-		memset(sin6, 0, sizeof(*sin6));
-		sin6->sin6_len = m->m_len = sizeof (struct sockaddr_in6);
-		sin6->sin6_family = AF_INET6;
-		error = sobind(so, m, &lwp0);
-		m_freem(m);
+		memset(&sin6, 0, sizeof(sin6));
+		sin6.sin6_len = sizeof(struct sockaddr_in6);
+		sin6.sin6_family = AF_INET6;
+		error = sobind(so, (struct sockaddr *)&sin6, &lwp0);
 		if (error)
 			goto bad;
 	}
Index: sys/rump/net/lib/libsockin/sockin.c
===================================================================
RCS file: /cvsroot/src/sys/rump/net/lib/libsockin/sockin.c,v
retrieving revision 1.58
diff -u -p -r1.58 sockin.c
--- sys/rump/net/lib/libsockin/sockin.c	9 Aug 2014 05:33:01 -0000	1.58
+++ sys/rump/net/lib/libsockin/sockin.c	14 Mar 2015 14:47:38 -0000
@@ -70,7 +70,7 @@ static int	sockin_attach(struct socket *
 static void	sockin_detach(struct socket *);
 static int	sockin_accept(struct socket *, struct mbuf *);
 static int	sockin_connect2(struct socket *, struct socket *);
-static int	sockin_bind(struct socket *, struct mbuf *, struct lwp *);
+static int	sockin_bind(struct socket *, struct sockaddr *, struct lwp *);
 static int	sockin_listen(struct socket *, struct lwp *);
 static int	sockin_connect(struct socket *, struct mbuf *, struct lwp *);
 static int	sockin_disconnect(struct socket *);
@@ -494,14 +494,12 @@ sockin_accept(struct socket *so, struct 
 }
 
 static int
-sockin_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+sockin_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
 {
 	KASSERT(solocked(so));
 	KASSERT(nam != NULL);
 
-	return rumpcomp_sockin_bind(SO2S(so),
-	    mtod(nam, const struct sockaddr *),
-	    nam->m_len);
+	return rumpcomp_sockin_bind(SO2S(so), nam, nam->sa_len);
 }
 
 static int
Index: sys/sys/protosw.h
===================================================================
RCS file: /cvsroot/src/sys/sys/protosw.h,v
retrieving revision 1.60
diff -u -p -r1.60 protosw.h
--- sys/sys/protosw.h	9 Aug 2014 05:33:01 -0000	1.60
+++ sys/sys/protosw.h	14 Mar 2015 14:47:38 -0000
@@ -241,7 +241,7 @@ struct pr_usrreqs {
 	int	(*pr_accept)(struct socket *, struct mbuf *);
 	int	(*pr_connect)(struct socket *, struct mbuf *, struct lwp *);
 	int	(*pr_connect2)(struct socket *, struct socket *);
-	int	(*pr_bind)(struct socket *, struct mbuf *, struct lwp *);
+	int	(*pr_bind)(struct socket *, struct sockaddr *, struct lwp *);
 	int	(*pr_listen)(struct socket *, struct lwp *);
 	int	(*pr_disconnect)(struct socket *);
 	int	(*pr_shutdown)(struct socket *);
@@ -317,8 +317,8 @@ name##_accept_wrapper(struct socket *a, 
 	return rv;					\
 }							\
 static int						\
-name##_bind_wrapper(struct socket *a, struct mbuf *b,	\
-    struct lwp *c)					\
+name##_bind_wrapper(struct socket *a,			\
+    struct sockaddr *b,	struct lwp *c)			\
 {							\
 	int rv;						\
 	KERNEL_LOCK(1, NULL);				\
Index: sys/sys/socket.h
===================================================================
RCS file: /cvsroot/src/sys/sys/socket.h,v
retrieving revision 1.116
diff -u -p -r1.116 socket.h
--- sys/sys/socket.h	10 Feb 2015 19:11:52 -0000	1.116
+++ sys/sys/socket.h	14 Mar 2015 14:47:38 -0000
@@ -242,6 +242,24 @@ struct sockproto {
 	u_short	sp_family;		/* address family */
 	u_short	sp_protocol;		/* protocol */
 };
+
+/*
+ * we make the entire struct at least UCHAR_MAX + 1 in size since existing
+ * use of sockaddr_un permits a path up to 253 bytes + '\0'.
+ * sizeof(sb_len) + sizeof(sb_family) + 253 + '\0'
+ */
+#define _SB_DATASIZE	254
+struct sockaddr_big {
+    union {
+	struct {
+	    __uint8_t	sb_len;
+	    sa_family_t	sb_family;
+	    char	sb_data[_SB_DATASIZE];
+	};
+	uint64_t dummy; /* solicit natural alignment */
+    };
+};
+
 #endif /* _KERNEL */
 
 #if 1
Index: sys/sys/socketvar.h
===================================================================
RCS file: /cvsroot/src/sys/sys/socketvar.h,v
retrieving revision 1.135
diff -u -p -r1.135 socketvar.h
--- sys/sys/socketvar.h	5 Sep 2014 05:37:37 -0000	1.135
+++ sys/sys/socketvar.h	14 Mar 2015 14:47:38 -0000
@@ -289,7 +289,7 @@ void	soinit2(void);
 int	soabort(struct socket *);
 int	soaccept(struct socket *, struct mbuf *);
 int	sofamily(const struct socket *);
-int	sobind(struct socket *, struct mbuf *, struct lwp *);
+int	sobind(struct socket *, struct sockaddr *, struct lwp *);
 void	socantrcvmore(struct socket *);
 void	socantsendmore(struct socket *);
 int	soclose(struct socket *);
@@ -354,7 +354,7 @@ int	do_sys_sendmsg(struct lwp *, int, st
 int	do_sys_recvmsg(struct lwp *, int, struct msghdr *, struct mbuf **,
 	    struct mbuf **, register_t *);
 
-int	do_sys_bind(struct lwp *, int, struct mbuf *);
+int	do_sys_bind(struct lwp *, int, struct sockaddr *);
 int	do_sys_connect(struct lwp *, int, struct mbuf *);
 int	do_sys_accept(struct lwp *, int, struct mbuf **, register_t *,
 	    const sigset_t *, int, int);


Home | Main Index | Thread Index | Old Index