diff --git a/sys/cam/ctl/ctl_ha.c b/sys/cam/ctl/ctl_ha.c index 0828c46c886..695006ed99e 100644 --- a/sys/cam/ctl/ctl_ha.c +++ b/sys/cam/ctl/ctl_ha.c @@ -397,7 +397,7 @@ static int ctl_ha_accept(struct ha_softc *softc) { struct socket *lso, *so; - struct sockaddr *sap; + struct sockaddr_in sin = { .sin_len = sizeof(sin) }; int error; lso = softc->ha_lso; @@ -410,16 +410,11 @@ ctl_ha_accept(struct ha_softc *softc) goto out; } - sap = NULL; - error = soaccept(so, &sap); + error = soaccept(so, (struct sockaddr *)&sin); if (error != 0) { printf("%s: soaccept() error %d\n", __func__, error); - if (sap != NULL) - free(sap, M_SONAME); goto out; } - if (sap != NULL) - free(sap, M_SONAME); softc->ha_so = so; ctl_ha_sock_setup(softc); return (0); diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index a5ed5c5c62d..2893e93bbcd 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1017,31 +1017,29 @@ static int linux_accept_common(struct thread *td, int s, l_uintptr_t addr, l_uintptr_t namelen, int flags) { - struct sockaddr *sa; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; struct file *fp, *fp1; - int bflags, len; struct socket *so; - int error, error1; + socklen_t len; + int bflags, error, error1; bflags = 0; fp = NULL; - sa = NULL; error = linux_set_socket_flags(flags, &bflags); if (error != 0) return (error); - if (PTRIN(addr) == NULL) { - len = 0; - error = kern_accept4(td, s, NULL, NULL, bflags, NULL); - } else { + if (PTRIN(addr) != NULL) { error = copyin(PTRIN(namelen), &len, sizeof(len)); if (error != 0) return (error); if (len < 0) return (EINVAL); - error = kern_accept4(td, s, &sa, &len, bflags, &fp); - } + } else + len = 0; + + error = kern_accept4(td, s, (struct sockaddr *)&ss, bflags, &fp); /* * Translate errno values into ones used by Linux. @@ -1071,11 +1069,14 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr, return (error); } - if (len != 0) { - error = linux_copyout_sockaddr(sa, PTRIN(addr), len); - if (error == 0) - error = copyout(&len, PTRIN(namelen), - sizeof(len)); + if (PTRIN(addr) != NULL) { + len = min(ss.ss_len, len); + error = linux_copyout_sockaddr((struct sockaddr *)&ss, + PTRIN(addr), len); + if (error == 0) { + len = ss.ss_len; + error = copyout(&len, PTRIN(namelen), sizeof(len)); + } if (error != 0) { fdclose(td, fp, td->td_retval[0]); td->td_retval[0] = 0; @@ -1083,7 +1084,6 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr, } if (fp != NULL) fdrop(fp, td); - free(sa, M_SONAME); return (error); } diff --git a/sys/dev/cxgbe/iw_cxgbe/cm.c b/sys/dev/cxgbe/iw_cxgbe/cm.c index 77158eb855d..84d6df3f283 100644 --- a/sys/dev/cxgbe/iw_cxgbe/cm.c +++ b/sys/dev/cxgbe/iw_cxgbe/cm.c @@ -974,7 +974,7 @@ process_newconn(struct c4iw_listen_ep *master_lep, struct socket *new_so) { struct c4iw_listen_ep *real_lep = NULL; struct c4iw_ep *new_ep = NULL; - struct sockaddr_in *remote = NULL; + struct sockaddr_storage remote = { .ss_len = sizeof(remote) }; int ret = 0; MPASS(new_so != NULL); @@ -1019,19 +1019,16 @@ process_newconn(struct c4iw_listen_ep *master_lep, struct socket *new_so) new_ep->com.state = MPA_REQ_WAIT; setiwsockopt(new_so); - ret = soaccept(new_so, (struct sockaddr **)&remote); + ret = soaccept(new_so, (struct sockaddr *)&remote); if (ret != 0) { CTR4(KTR_IW_CXGBE, "%s:listen sock:%p, new sock:%p, ret:%d", __func__, master_lep->com.so, new_so, ret); - if (remote != NULL) - free(remote, M_SONAME); soclose(new_so); c4iw_put_ep(&new_ep->com); c4iw_put_ep(&real_lep->com); return; } - free(remote, M_SONAME); START_EP_TIMER(new_ep); diff --git a/sys/dev/hyperv/hvsock/hv_sock.c b/sys/dev/hyperv/hvsock/hv_sock.c index 60cdfecf3be..655cc990876 100644 --- a/sys/dev/hyperv/hvsock/hv_sock.c +++ b/sys/dev/hyperv/hvsock/hv_sock.c @@ -478,7 +478,7 @@ hvs_trans_listen(struct socket *so, int backlog, struct thread *td) } int -hvs_trans_accept(struct socket *so, struct sockaddr **nam) +hvs_trans_accept(struct socket *so, struct sockaddr *sa) { struct hvs_pcb *pcb = so2hvspcb(so); @@ -488,10 +488,9 @@ hvs_trans_accept(struct socket *so, struct sockaddr **nam) if (pcb == NULL) return (EINVAL); - *nam = sodupsockaddr((struct sockaddr *) &pcb->remote_addr, - M_NOWAIT); + memcpy(sa, &pcb->remote_addr, pcb->remote_addr.sa_len); - return ((*nam == NULL) ? ENOMEM : 0); + return (0); } int diff --git a/sys/dev/hyperv/hvsock/hv_sock.h b/sys/dev/hyperv/hvsock/hv_sock.h index 98a9afb747b..ee6416a2966 100644 --- a/sys/dev/hyperv/hvsock/hv_sock.h +++ b/sys/dev/hyperv/hvsock/hv_sock.h @@ -100,7 +100,7 @@ void hvs_trans_abort(struct socket *); int hvs_trans_attach(struct socket *, int, struct thread *); int hvs_trans_bind(struct socket *, struct sockaddr *, struct thread *); int hvs_trans_listen(struct socket *, int, struct thread *); -int hvs_trans_accept(struct socket *, struct sockaddr **); +int hvs_trans_accept(struct socket *, struct sockaddr *); int hvs_trans_connect(struct socket *, struct sockaddr *, struct thread *); int hvs_trans_peeraddr(struct socket *, struct sockaddr **); diff --git a/sys/dev/iscsi/icl_soft_proxy.c b/sys/dev/iscsi/icl_soft_proxy.c index ee448116b0e..db9bf12a688 100644 --- a/sys/dev/iscsi/icl_soft_proxy.c +++ b/sys/dev/iscsi/icl_soft_proxy.c @@ -205,7 +205,7 @@ icl_accept_thread(void *arg) { struct icl_listen_sock *ils; struct socket *head, *so; - struct sockaddr *sa; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; int error; ils = arg; @@ -231,17 +231,15 @@ icl_accept_thread(void *arg) continue; } - sa = NULL; - error = soaccept(so, &sa); + error = soaccept(so, (struct sockaddr *)&ss); if (error != 0) { ICL_WARN("soaccept error %d", error); - if (sa != NULL) - free(sa, M_SONAME); soclose(so); continue; } - (ils->ils_listen->il_accept)(so, sa, ils->ils_id); + (ils->ils_listen->il_accept)(so, (struct sockaddr *)&ss, + ils->ils_id); } } diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 03e6856b775..cf9b9151157 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -53,7 +53,7 @@ static struct mtx dom_mtx; /* domain list lock */ MTX_SYSINIT(domain, &dom_mtx, "domain list", MTX_DEF); static int -pr_accept_notsupp(struct socket *so, struct sockaddr **nam) +pr_accept_notsupp(struct socket *so, struct sockaddr *sa) { return (EOPNOTSUPP); } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index b59051ae335..d16c0049dc4 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1348,12 +1348,17 @@ soabort(struct socket *so) } int -soaccept(struct socket *so, struct sockaddr **nam) +soaccept(struct socket *so, struct sockaddr *sa) { +#ifdef INVARIANTS + u_char len = sa->sa_len; +#endif int error; CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_accept(so, nam); + error = so->so_proto->pr_accept(so, sa); + KASSERT(sa->sa_len <= len, + ("%s: protocol %p sockaddr overflow", __func__, so->so_proto)); CURVNET_RESTORE(); return (error); } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index a7ffb6ef325..0361144f276 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -277,19 +277,18 @@ static int accept1(struct thread *td, int s, struct sockaddr *uname, socklen_t *anamelen, int flags) { - struct sockaddr *name; - socklen_t namelen; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; + socklen_t addrlen; struct file *fp; int error; - if (uname == NULL) - return (kern_accept4(td, s, NULL, NULL, flags, NULL)); + if (uname != NULL) { + error = copyin(anamelen, &addrlen, sizeof(addrlen)); + if (error != 0) + return (error); + } - error = copyin(anamelen, &namelen, sizeof (namelen)); - if (error != 0) - return (error); - - error = kern_accept4(td, s, &name, &namelen, flags, &fp); + error = kern_accept4(td, s, (struct sockaddr *)&ss, flags, &fp); if (error != 0) return (error); @@ -297,42 +296,40 @@ accept1(struct thread *td, int s, struct sockaddr *uname, socklen_t *anamelen, #ifdef COMPAT_OLDSOCK if (SV_PROC_FLAG(td->td_proc, SV_AOUT) && (flags & ACCEPT4_COMPAT) != 0) - ((struct osockaddr *)name)->sa_family = - name->sa_family; + ((struct osockaddr *)&ss)->sa_family = ss.ss_family; #endif - error = copyout(name, uname, namelen); - if (error == 0) - error = copyout(&namelen, anamelen, - sizeof(namelen)); + if (uname != NULL) { + addrlen = min(ss.ss_len, addrlen); + error = copyout(&ss, uname, addrlen); + if (error == 0) { + addrlen = ss.ss_len; + error = copyout(&addrlen, anamelen, sizeof(addrlen)); + } + } if (error != 0) fdclose(td, fp, td->td_retval[0]); fdrop(fp, td); - free(name, M_SONAME); + return (error); } int -kern_accept(struct thread *td, int s, struct sockaddr **name, - socklen_t *namelen, struct file **fp) +kern_accept(struct thread *td, int s, struct sockaddr *sa, struct file **fp) { - return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp)); + return (kern_accept4(td, s, sa, ACCEPT4_INHERIT, fp)); } int -kern_accept4(struct thread *td, int s, struct sockaddr **name, - socklen_t *namelen, int flags, struct file **fp) +kern_accept4(struct thread *td, int s, struct sockaddr *sa, int flags, + struct file **fp) { struct file *headfp, *nfp = NULL; - struct sockaddr *sa = NULL; struct socket *head, *so; struct filecaps fcaps; u_int fflag; pid_t pgid; int error, fd, tmp; - if (name != NULL) - *name = NULL; - AUDIT_ARG_FD(s); error = getsock_cap(td, s, &cap_accept_rights, &headfp, &fcaps); @@ -386,29 +383,15 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td); tmp = fflag & FASYNC; (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td); - error = soaccept(so, &sa); - if (error != 0) - goto noconnection; - if (sa == NULL) { - if (name) - *namelen = 0; - goto done; - } - AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa); - if (name) { - /* check sa_len before it is destroyed */ - if (*namelen > sa->sa_len) - *namelen = sa->sa_len; + + if ((error = soaccept(so, sa)) == 0) { + AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa); #ifdef KTRACE if (KTRPOINT(td, KTR_STRUCT)) ktrsockaddr(sa); #endif - *name = sa; - sa = NULL; } noconnection: - free(sa, M_SONAME); - /* * close the new descriptor, assuming someone hasn't ripped it * out from under us. diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 53a7c2b2915..3071a5169b7 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -120,7 +120,10 @@ struct unp_defer { static SLIST_HEAD(, unp_defer) unp_defers; static int unp_defers_count; -static const struct sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL }; +static const struct sockaddr sun_noname = { + .sa_len = sizeof(sun_noname), + .sa_family = AF_LOCAL, +}; /* * Garbage collection of cyclic file descriptor/socket references occurs @@ -434,7 +437,7 @@ uipc_abort(struct socket *so) } static int -uipc_accept(struct socket *so, struct sockaddr **nam) +uipc_accept(struct socket *so, struct sockaddr *ret) { struct unpcb *unp, *unp2; const struct sockaddr *sa; @@ -446,14 +449,13 @@ uipc_accept(struct socket *so, struct sockaddr **nam) unp = sotounpcb(so); KASSERT(unp != NULL, ("uipc_accept: unp == NULL")); - *nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK); UNP_PCB_LOCK(unp); unp2 = unp_pcb_lock_peer(unp); if (unp2 != NULL && unp2->unp_addr != NULL) sa = (struct sockaddr *)unp2->unp_addr; else sa = &sun_noname; - bcopy(sa, *nam, sa->sa_len); + bcopy(sa, ret, sa->sa_len); if (unp2 != NULL) unp_pcb_unlock_pair(unp, unp2); else diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h index baaef9abb73..b512112f8b7 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h @@ -191,7 +191,7 @@ typedef struct ng_btsocket_l2cap_pcb * ng_btsocket_l2cap_pcb_p; void ng_btsocket_l2cap_abort (struct socket *); void ng_btsocket_l2cap_close (struct socket *); -int ng_btsocket_l2cap_accept (struct socket *, struct sockaddr **); +int ng_btsocket_l2cap_accept (struct socket *, struct sockaddr *); int ng_btsocket_l2cap_attach (struct socket *, int, struct thread *); int ng_btsocket_l2cap_bind (struct socket *, struct sockaddr *, struct thread *); diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h index 88c0f898858..d40b694ece1 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h @@ -316,7 +316,7 @@ typedef struct ng_btsocket_rfcomm_pcb * ng_btsocket_rfcomm_pcb_p; void ng_btsocket_rfcomm_abort (struct socket *); void ng_btsocket_rfcomm_close (struct socket *); -int ng_btsocket_rfcomm_accept (struct socket *, struct sockaddr **); +int ng_btsocket_rfcomm_accept (struct socket *, struct sockaddr *); int ng_btsocket_rfcomm_attach (struct socket *, int, struct thread *); int ng_btsocket_rfcomm_bind (struct socket *, struct sockaddr *, struct thread *); diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h b/sys/netgraph/bluetooth/include/ng_btsocket_sco.h index 071ddb8d80e..282980cce88 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_sco.h @@ -106,7 +106,7 @@ typedef struct ng_btsocket_sco_pcb * ng_btsocket_sco_pcb_p; void ng_btsocket_sco_abort (struct socket *); void ng_btsocket_sco_close (struct socket *); -int ng_btsocket_sco_accept (struct socket *, struct sockaddr **); +int ng_btsocket_sco_accept (struct socket *, struct sockaddr *); int ng_btsocket_sco_attach (struct socket *, int, struct thread *); int ng_btsocket_sco_bind (struct socket *, struct sockaddr *, struct thread *); diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c index 8fc64bb7092..d221cc34d36 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c @@ -1967,20 +1967,6 @@ ng_btsocket_l2cap_close(struct socket *so) (void)ng_btsocket_l2cap_disconnect(so); } /* ng_btsocket_l2cap_close */ -/* - * Accept connection on socket. Nothing to do here, socket must be connected - * and ready, so just return peer address and be done with it. - */ - -int -ng_btsocket_l2cap_accept(struct socket *so, struct sockaddr **nam) -{ - if (ng_btsocket_l2cap_node == NULL) - return (EINVAL); - - return (ng_btsocket_l2cap_peeraddr(so, nam)); -} /* ng_btsocket_l2cap_accept */ - /* * Create and attach new socket */ @@ -2523,41 +2509,67 @@ out: return (error); } /* ng_btsocket_listen */ -/* - * Get peer address - */ - -int -ng_btsocket_l2cap_peeraddr(struct socket *so, struct sockaddr **nam) +static int +ng_btsocket_l2cap_peeraddr1(struct socket *so, struct sockaddr_l2cap *sa) { ng_btsocket_l2cap_pcb_p pcb = so2l2cap_pcb(so); - struct sockaddr_l2cap sa; if (pcb == NULL) return (EINVAL); if (ng_btsocket_l2cap_node == NULL) return (EINVAL); - bcopy(&pcb->dst, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr)); - sa.l2cap_psm = htole16(pcb->psm); - sa.l2cap_len = sizeof(sa); - sa.l2cap_family = AF_BLUETOOTH; + *sa = (struct sockaddr_l2cap ){ + .l2cap_len = sizeof(struct sockaddr_l2cap), + .l2cap_family = AF_BLUETOOTH, + .l2cap_psm = htole16(pcb->psm), + }; + bcopy(&pcb->dst, &sa->l2cap_bdaddr, sizeof(sa->l2cap_bdaddr)); switch(pcb->idtype){ case NG_L2CAP_L2CA_IDTYPE_ATT: - sa.l2cap_cid = NG_L2CAP_ATT_CID; + sa->l2cap_cid = NG_L2CAP_ATT_CID; break; case NG_L2CAP_L2CA_IDTYPE_SMP: - sa.l2cap_cid = NG_L2CAP_SMP_CID; + sa->l2cap_cid = NG_L2CAP_SMP_CID; break; default: - sa.l2cap_cid = 0; + sa->l2cap_cid = 0; break; } - sa.l2cap_bdaddr_type = pcb->dsttype; + sa->l2cap_bdaddr_type = pcb->dsttype; + + return (0); +} + +/* + * Get peer address + */ +int +ng_btsocket_l2cap_peeraddr(struct socket *so, struct sockaddr **nam) +{ + struct sockaddr_l2cap sa; + int error; + + error = ng_btsocket_l2cap_peeraddr1(so, &sa); + if (error != 0) + return (error); *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); return ((*nam == NULL)? ENOMEM : 0); -} /* ng_btsocket_l2cap_peeraddr */ +} + +/* + * Accept connection on socket. Nothing to do here, socket must be connected + * and ready, so just return peer address and be done with it. + */ +int +ng_btsocket_l2cap_accept(struct socket *so, struct sockaddr *sa) +{ + if (ng_btsocket_l2cap_node == NULL) + return (EINVAL); + + return (ng_btsocket_l2cap_peeraddr1(so, (struct sockaddr_l2cap *)sa)); +} /* * Send data to socket diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c index 00225f8240e..af542f3c258 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c @@ -370,17 +370,6 @@ ng_btsocket_rfcomm_close(struct socket *so) (void)ng_btsocket_rfcomm_disconnect(so); } /* ng_btsocket_rfcomm_close */ -/* - * Accept connection on socket. Nothing to do here, socket must be connected - * and ready, so just return peer address and be done with it. - */ - -int -ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr **nam) -{ - return (ng_btsocket_rfcomm_peeraddr(so, nam)); -} /* ng_btsocket_rfcomm_accept */ - /* * Create and attach new socket */ @@ -925,28 +914,51 @@ out: return (error); } /* ng_btsocket_listen */ -/* - * Get peer address - */ - -int -ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam) +static int +ng_btsocket_rfcomm_peeraddr1(struct socket *so, struct sockaddr_rfcomm *sa) { ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); - struct sockaddr_rfcomm sa; if (pcb == NULL) return (EINVAL); - bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); - sa.rfcomm_channel = pcb->channel; - sa.rfcomm_len = sizeof(sa); - sa.rfcomm_family = AF_BLUETOOTH; + *sa = (struct sockaddr_rfcomm ){ + .rfcomm_len = sizeof(struct sockaddr_rfcomm), + .rfcomm_family = AF_BLUETOOTH, + .rfcomm_channel = pcb->channel, + }; + bcopy(&pcb->dst, &sa->rfcomm_bdaddr, sizeof(sa->rfcomm_bdaddr)); + return (0); +} + +/* + * Get peer address + */ +int +ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam) +{ + struct sockaddr_rfcomm sa; + int error; + + error = ng_btsocket_rfcomm_peeraddr1(so, &sa); + if (error != 0) + return (error); *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); return ((*nam == NULL)? ENOMEM : 0); -} /* ng_btsocket_rfcomm_peeraddr */ +} + +/* + * Accept connection on socket. Nothing to do here, socket must be connected + * and ready, so just return peer address and be done with it. + */ +int +ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr *sa) +{ + + return (ng_btsocket_rfcomm_peeraddr1(so, (struct sockaddr_rfcomm *)sa)); +} /* * Send data to socket @@ -1407,7 +1419,7 @@ static int ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) { struct socket *l2so; - struct sockaddr_l2cap *l2sa = NULL; + struct sockaddr_l2cap l2sa = { .l2cap_len = sizeof(l2sa) }; ng_btsocket_l2cap_pcb_t *l2pcb = NULL; ng_btsocket_rfcomm_session_p s = NULL; int error; @@ -1425,7 +1437,7 @@ ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) return (error); } - error = soaccept(l2so, (struct sockaddr **) &l2sa); + error = soaccept(l2so, (struct sockaddr *)&l2sa); if (error != 0) { NG_BTSOCKET_RFCOMM_ERR( "%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error); diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c b/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c index 5e198956a82..d9700f91c13 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c @@ -1176,20 +1176,6 @@ ng_btsocket_sco_close(struct socket *so) (void) ng_btsocket_sco_disconnect(so); } /* ng_btsocket_sco_close */ -/* - * Accept connection on socket. Nothing to do here, socket must be connected - * and ready, so just return peer address and be done with it. - */ - -int -ng_btsocket_sco_accept(struct socket *so, struct sockaddr **nam) -{ - if (ng_btsocket_sco_node == NULL) - return (EINVAL); - - return (ng_btsocket_sco_peeraddr(so, nam)); -} /* ng_btsocket_sco_accept */ - /* * Create and attach new socket */ @@ -1623,32 +1609,56 @@ out: return (error); } /* ng_btsocket_listen */ -/* - * Get peer address - */ - -int -ng_btsocket_sco_peeraddr(struct socket *so, struct sockaddr **nam) +static int +ng_btsocket_sco_peeraddr1(struct socket *so, struct sockaddr_sco *sa) { ng_btsocket_sco_pcb_p pcb = so2sco_pcb(so); - struct sockaddr_sco sa; if (pcb == NULL) return (EINVAL); if (ng_btsocket_sco_node == NULL) return (EINVAL); + *sa = (struct sockaddr_sco ){ + .sco_len = sizeof(struct sockaddr_sco), + .sco_family = AF_BLUETOOTH, + }; mtx_lock(&pcb->pcb_mtx); - bcopy(&pcb->dst, &sa.sco_bdaddr, sizeof(sa.sco_bdaddr)); + bcopy(&pcb->dst, &sa->sco_bdaddr, sizeof(sa->sco_bdaddr)); mtx_unlock(&pcb->pcb_mtx); - sa.sco_len = sizeof(sa); - sa.sco_family = AF_BLUETOOTH; + return (0); +} +/* + * Get peer address + */ +int +ng_btsocket_sco_peeraddr(struct socket *so, struct sockaddr **nam) +{ + struct sockaddr_sco sa; + int error; + + error = ng_btsocket_sco_peeraddr1(so, &sa); + if (error != 0) + return (error); *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); return ((*nam == NULL)? ENOMEM : 0); -} /* ng_btsocket_sco_peeraddr */ +} + +/* + * Accept connection on socket. Nothing to do here, socket must be connected + * and ready, so just return peer address and be done with it. + */ +int +ng_btsocket_sco_accept(struct socket *so, struct sockaddr *sa) +{ + if (ng_btsocket_sco_node == NULL) + return (EINVAL); + + return (ng_btsocket_sco_peeraddr1(so, (struct sockaddr_sco *)sa)); +} /* * Send data to socket diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c index 777f3261356..23a53528833 100644 --- a/sys/netgraph/ng_ksocket.c +++ b/sys/netgraph/ng_ksocket.c @@ -1178,7 +1178,7 @@ ng_ksocket_accept(priv_p priv) { struct socket *const head = priv->so; struct socket *so; - struct sockaddr *sa = NULL; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; struct ng_mesg *resp; struct ng_ksocket_accept *resp_data; node_p node; @@ -1196,12 +1196,11 @@ ng_ksocket_accept(priv_p priv) if (error) return (error); - if ((error = soaccept(so, &sa)) != 0) + if ((error = soaccept(so, (struct sockaddr *)&ss)) != 0) return (error); len = OFFSETOF(struct ng_ksocket_accept, addr); - if (sa != NULL) - len += sa->sa_len; + len += ss.ss_len; NG_MKMESSAGE(resp, NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT, len, M_NOWAIT); @@ -1249,13 +1248,10 @@ ng_ksocket_accept(priv_p priv) /* Fill in the response data and send it or return it to the caller */ resp_data = (struct ng_ksocket_accept *)resp->data; resp_data->nodeid = NG_NODE_ID(node); - if (sa != NULL) - bcopy(sa, &resp_data->addr, sa->sa_len); + bcopy(&ss, &resp_data->addr, ss.ss_len); NG_SEND_MSG_ID(error, node, resp, priv->response_addr, 0); out: - if (sa != NULL) - free(sa, M_SONAME); return (0); } diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 29d63f989e7..8fb96db84f9 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -7271,7 +7271,7 @@ out: static int sctp_defered_wakeup_cnt = 0; int -sctp_accept(struct socket *so, struct sockaddr **addr) +sctp_accept(struct socket *so, struct sockaddr *sa) { struct sctp_tcb *stcb; struct sctp_inpcb *inp; @@ -7338,39 +7338,25 @@ sctp_accept(struct socket *so, struct sockaddr **addr) switch (store.sa.sa_family) { #ifdef INET case AF_INET: - { - struct sockaddr_in *sin; - - SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); - if (sin == NULL) - return (ENOMEM); - sin->sin_family = AF_INET; - sin->sin_len = sizeof(*sin); - sin->sin_port = store.sin.sin_port; - sin->sin_addr = store.sin.sin_addr; - *addr = (struct sockaddr *)sin; - break; - } + *(struct sockaddr_in *)sa = (struct sockaddr_in ){ + .sin_family = AF_INET, + .sin_len = sizeof(struct sockaddr_in), + .sin_port = store.sin.sin_port, + .sin_addr = store.sin.sin_addr, + }; + break; #endif #ifdef INET6 case AF_INET6: - { - struct sockaddr_in6 *sin6; - - SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); - if (sin6 == NULL) - return (ENOMEM); - sin6->sin6_family = AF_INET6; - sin6->sin6_len = sizeof(*sin6); - sin6->sin6_port = store.sin6.sin6_port; - sin6->sin6_addr = store.sin6.sin6_addr; - if ((error = sa6_recoverscope(sin6)) != 0) { - SCTP_FREE_SONAME(sin6); - return (error); - } - *addr = (struct sockaddr *)sin6; - break; - } + *(struct sockaddr_in6 *)sa = (struct sockaddr_in6 ){ + .sin6_family = AF_INET6, + .sin6_len = sizeof(struct sockaddr_in6), + .sin6_port = store.sin6.sin6_port, + .sin6_addr = store.sin6.sin6_addr, + }; + if ((error = sa6_recoverscope((struct sockaddr_in6 *)sa)) != 0) + return (error); + break; #endif default: /* TSNH */ diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h index 3a649a1860e..ff6672bd024 100644 --- a/sys/netinet/sctp_var.h +++ b/sys/netinet/sctp_var.h @@ -341,7 +341,7 @@ int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *); int sctp_ingetaddr(struct socket *, struct sockaddr **); int sctp_peeraddr(struct socket *, struct sockaddr **); int sctp_listen(struct socket *, int, struct thread *); -int sctp_accept(struct socket *, struct sockaddr **); +int sctp_accept(struct socket *, struct sockaddr *); #endif /* _KERNEL */ diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index f89e60cce8c..14e0b814dec 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -717,13 +717,11 @@ out: * just return the address of the peer, storing through addr. */ static int -tcp_usr_accept(struct socket *so, struct sockaddr **nam) +tcp_usr_accept(struct socket *so, struct sockaddr *sa) { - int error = 0; struct inpcb *inp; struct tcpcb *tp; - struct in_addr addr; - in_port_t port = 0; + int error = 0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL")); @@ -734,39 +732,30 @@ tcp_usr_accept(struct socket *so, struct sockaddr **nam) } tp = intotcpcb(inp); - if (so->so_state & SS_ISDISCONNECTED) { + if (so->so_state & SS_ISDISCONNECTED) error = ECONNABORTED; - goto out; - } - /* - * We inline in_getpeeraddr and COMMON_END here, so that we can - * copy the data of interest and defer the malloc until after we - * release the lock. - */ - port = inp->inp_fport; - addr = inp->inp_faddr; - -out: + else + *(struct sockaddr_in *)sa = (struct sockaddr_in ){ + .sin_family = AF_INET, + .sin_len = sizeof(struct sockaddr_in), + .sin_port = inp->inp_fport, + .sin_addr = inp->inp_faddr, + }; tcp_bblog_pru(tp, PRU_ACCEPT, error); TCP_PROBE2(debug__user, tp, PRU_ACCEPT); INP_WUNLOCK(inp); - if (error == 0) - *nam = in_sockaddr(port, &addr); - return error; + + return (error); } #endif /* INET */ #ifdef INET6 static int -tcp6_usr_accept(struct socket *so, struct sockaddr **nam) +tcp6_usr_accept(struct socket *so, struct sockaddr *sa) { struct inpcb *inp; - int error = 0; struct tcpcb *tp; - struct in_addr addr; - struct in6_addr addr6; - in_port_t port = 0; - int v4 = 0; + int error = 0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL")); @@ -779,33 +768,32 @@ tcp6_usr_accept(struct socket *so, struct sockaddr **nam) if (so->so_state & SS_ISDISCONNECTED) { error = ECONNABORTED; - goto out; - } - /* - * We inline in6_mapped_peeraddr and COMMON_END here, so that we can - * copy the data of interest and defer the malloc until after we - * release the lock. - */ - if (inp->inp_vflag & INP_IPV4) { - v4 = 1; - port = inp->inp_fport; - addr = inp->inp_faddr; } else { - port = inp->inp_fport; - addr6 = inp->in6p_faddr; + if (inp->inp_vflag & INP_IPV4) { + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_len = sizeof(struct sockaddr_in), + .sin_port = inp->inp_fport, + .sin_addr = inp->inp_faddr, + }; + in6_sin_2_v4mapsin6(&sin, (struct sockaddr_in6 *)sa); + } else { + *(struct sockaddr_in6 *)sa = (struct sockaddr_in6 ){ + .sin6_family = AF_INET6, + .sin6_len = sizeof(struct sockaddr_in6), + .sin6_port = inp->inp_fport, + .sin6_addr = inp->in6p_faddr, + }; + /* XXX: should catch errors */ + (void)sa6_recoverscope((struct sockaddr_in6 *)sa); + } } -out: tcp_bblog_pru(tp, PRU_ACCEPT, error); TCP_PROBE2(debug__user, tp, PRU_ACCEPT); INP_WUNLOCK(inp); - if (error == 0) { - if (v4) - *nam = in6_v4mapsin6_sockaddr(port, &addr); - else - *nam = in6_sockaddr(port, &addr6); - } - return error; + + return (error); } #endif /* INET6 */ diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 375f762e1cc..d44e5c2cddb 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -517,25 +517,6 @@ in6_sockaddr(in_port_t port, struct in6_addr *addr_p) return (struct sockaddr *)sin6; } -struct sockaddr * -in6_v4mapsin6_sockaddr(in_port_t port, struct in_addr *addr_p) -{ - struct sockaddr_in sin; - struct sockaddr_in6 *sin6_p; - - bzero(&sin, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_len = sizeof(sin); - sin.sin_port = port; - sin.sin_addr = *addr_p; - - sin6_p = malloc(sizeof *sin6_p, M_SONAME, - M_WAITOK); - in6_sin_2_v4mapsin6(&sin, sin6_p); - - return (struct sockaddr *)sin6_p; -} - int in6_getsockaddr(struct socket *so, struct sockaddr **nam) { diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h index 4eba1e47dec..acccc279fdc 100644 --- a/sys/netinet6/in6_pcb.h +++ b/sys/netinet6/in6_pcb.h @@ -98,8 +98,6 @@ struct inpcb * in6_rtchange(struct inpcb *, int); struct sockaddr * in6_sockaddr(in_port_t port, struct in6_addr *addr_p); -struct sockaddr * - in6_v4mapsin6_sockaddr(in_port_t port, struct in_addr *addr_p); int in6_getpeeraddr(struct socket *so, struct sockaddr **nam); int in6_getsockaddr(struct socket *so, struct sockaddr **nam); int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam); diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c index f70c92e8b29..a2d5f12f27a 100644 --- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c +++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c @@ -776,32 +776,29 @@ out: * are fully initialized. */ static int -sdp_accept(struct socket *so, struct sockaddr **nam) +sdp_accept(struct socket *so, struct sockaddr *sa) { struct sdp_sock *ssk = NULL; - struct in_addr addr; - in_port_t port; int error; if (so->so_state & SS_ISDISCONNECTED) return (ECONNABORTED); - port = 0; - addr.s_addr = 0; error = 0; ssk = sdp_sk(so); SDP_WLOCK(ssk); - if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED)) { + if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED)) error = ECONNABORTED; - goto out; - } - port = ssk->fport; - addr.s_addr = ssk->faddr; -out: + else + *(struct sockaddr_in *)sa = (struct sockaddr_in ){ + .sin_family = AF_INET, + .sin_len = sizeof(struct sockaddr_in), + .sin_addr.s_addr = ssk->faddr, + .sin_port = ssk->fport, + }; SDP_WUNLOCK(ssk); - if (error == 0) - *nam = sdp_sockaddr(port, &addr); - return error; + + return (error); } /* diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index 7eac2bc8f74..a19d73a850b 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -420,7 +420,7 @@ svc_vc_rendezvous_recv(SVCXPRT *xprt, struct rpc_msg *msg, struct sockaddr **addrp, struct mbuf **mp) { struct socket *so = NULL; - struct sockaddr *sa = NULL; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; int error; SVCXPRT *new_xprt; @@ -464,15 +464,12 @@ svc_vc_rendezvous_recv(SVCXPRT *xprt, struct rpc_msg *msg, sx_xunlock(&xprt->xp_lock); - sa = NULL; - error = soaccept(so, &sa); + error = soaccept(so, (struct sockaddr *)&ss); if (error) { /* * XXX not sure if I need to call sofree or soclose here. */ - if (sa) - free(sa, M_SONAME); return (FALSE); } @@ -480,15 +477,14 @@ svc_vc_rendezvous_recv(SVCXPRT *xprt, struct rpc_msg *msg, * svc_vc_create_conn will call xprt_register - we don't need * to do anything with the new connection except derefence it. */ - new_xprt = svc_vc_create_conn(xprt->xp_pool, so, sa); + new_xprt = svc_vc_create_conn(xprt->xp_pool, so, + (struct sockaddr *)&ss); if (!new_xprt) { soclose(so); } else { SVC_RELEASE(new_xprt); } - free(sa, M_SONAME); - return (FALSE); /* there is never an rpc msg to be processed */ } diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 469e845b64b..629e7570cb7 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -61,7 +61,7 @@ struct uio; typedef int pr_ctloutput_t(struct socket *, struct sockopt *); typedef int pr_setsbopt_t(struct socket *, struct sockopt *); typedef void pr_abort_t(struct socket *); -typedef int pr_accept_t(struct socket *, struct sockaddr **); +typedef int pr_accept_t(struct socket *, struct sockaddr *); typedef int pr_attach_t(struct socket *, int, struct thread *); typedef int pr_bind_t(struct socket *, struct sockaddr *, struct thread *); typedef int pr_connect_t(struct socket *, struct sockaddr *, diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 52523b99686..005938aee08 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -449,7 +449,7 @@ int getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp, int getsock(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); void soabort(struct socket *so); -int soaccept(struct socket *so, struct sockaddr **nam); +int soaccept(struct socket *so, struct sockaddr *sa); void soaio_enqueue(struct task *task); void soaio_rcv(void *context, int pending); void soaio_snd(void *context, int pending); diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 0480eda2fca..c28016b4b3f 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -84,10 +84,10 @@ int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen, size_t path_max); int kern_abort2(struct thread *td, const char *why, int nargs, void **uargs); -int kern_accept(struct thread *td, int s, struct sockaddr **name, - socklen_t *namelen, struct file **fp); -int kern_accept4(struct thread *td, int s, struct sockaddr **name, - socklen_t *namelen, int flags, struct file **fp); +int kern_accept(struct thread *td, int s, struct sockaddr *sa, + struct file **fp); +int kern_accept4(struct thread *td, int s, struct sockaddr *sa, + int flags, struct file **fp); int kern_accessat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, int flags, int mode); int kern_adjtime(struct thread *td, struct timeval *delta, diff --git a/tests/sys/kern/socket_accept.c b/tests/sys/kern/socket_accept.c index 278eb2fb985..24c3210900d 100644 --- a/tests/sys/kern/socket_accept.c +++ b/tests/sys/kern/socket_accept.c @@ -81,10 +81,7 @@ ATF_TC_BODY(tcp4_zerolen, tc) salen = 0; ATF_REQUIRE(accept(l, (struct sockaddr *)&ret, &salen) > 0); ATF_REQUIRE(memcmp(&ret, &canary, sizeof(ret)) == 0); -#if 0 - /* Linux behavior. Matches my reading of accept(2) and POSIX. */ ATF_REQUIRE(salen == sizeof(struct sockaddr_in)); -#endif /* Note: Linux will block for connection here, we fail immediately. */ ATF_REQUIRE(accept(l, (struct sockaddr *)&ret, NULL) == -1); ATF_REQUIRE(errno == EFAULT);