diff options
author | Matthew Dempsky <matthew@cvs.openbsd.org> | 2012-05-06 20:25:28 +0000 |
---|---|---|
committer | Matthew Dempsky <matthew@cvs.openbsd.org> | 2012-05-06 20:25:28 +0000 |
commit | c27e24609a954966a6597c8a68ceb55551ba9303 (patch) | |
tree | 1c1b0adcedbbb21d9220fc7e2ca910bf3c7ae4d8 /sys | |
parent | 30941b37f71b9f0850fa6e7038ba27f61e336ccf (diff) |
Change accept(), recvfrom(), recvmsg(), getsockname(), and
getpeername() to return the untruncated address length in *addrlen
instead of the number of bytes copied out. This matches POSIX's
requirements and allows userland applications to detect when the
returned address was truncated.
ok guenther
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/uipc_syscalls.c | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 297bb96572d..a1407a71d46 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.85 2012/04/22 05:43:14 guenther Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.86 2012/05/06 20:25:27 matthew Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -61,6 +61,9 @@ */ extern struct fileops socketops; +int copyaddrout(struct proc *, struct mbuf *, struct sockaddr *, socklen_t, + socklen_t *); + int sys_socket(struct proc *p, void *v, register_t *retval) { @@ -118,8 +121,8 @@ sys_bind(struct proc *p, void *v, register_t *retval) MT_SONAME); if (error == 0) { #ifdef KTRACE - if (KTRPOINT(p, KTR_STRUCT)) - ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen)); + if (KTRPOINT(p, KTR_STRUCT)) + ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen)); #endif error = sobind(fp->f_data, nam, p); m_freem(nam); @@ -235,18 +238,8 @@ sys_accept(struct proc *p, void *v, register_t *retval) nam = m_get(M_WAIT, MT_SONAME); error = soaccept(so, nam); if (!error && SCARG(uap, name)) { - if (namelen > nam->m_len) - namelen = nam->m_len; - /* SHOULD COPY OUT A CHAIN HERE */ - if ((error = copyout(mtod(nam, caddr_t), - SCARG(uap, name), namelen)) == 0) { -#ifdef KTRACE - if (KTRPOINT(p, KTR_STRUCT)) - ktrsockaddr(p, mtod(nam, caddr_t), namelen); -#endif - error = copyout(&namelen, SCARG(uap, anamelen), - sizeof (*SCARG(uap, anamelen))); - } + error = copyaddrout(p, nam, SCARG(uap, name), namelen, + SCARG(uap, anamelen)); } if (error) { @@ -690,16 +683,15 @@ recvit(struct proc *p, int s, struct msghdr *mp, caddr_t namelenp, if (from == NULL) alen = 0; else { - alen = MIN(from->m_len, mp->msg_namelen); + alen = from->m_len; error = copyout(mtod(from, caddr_t), mp->msg_name, - alen); + MIN(alen, mp->msg_namelen)); if (error) goto out; #ifdef KTRACE if (KTRPOINT(p, KTR_STRUCT)) ktrsockaddr(p, mtod(from, caddr_t), alen); #endif - } mp->msg_namelen = alen; if (namelenp && @@ -886,16 +878,7 @@ sys_getsockname(struct proc *p, void *v, register_t *retval) error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0, p); if (error) goto bad; - if (len > m->m_len) - len = m->m_len; - error = copyout(mtod(m, caddr_t), SCARG(uap, asa), len); - if (error == 0) { -#ifdef KTRACE - if (KTRPOINT(p, KTR_STRUCT)) - ktrsockaddr(p, mtod(m, caddr_t), len); -#endif - error = copyout(&len, SCARG(uap, alen), sizeof (len)); - } + error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen)); bad: FRELE(fp, p); if (m) @@ -935,16 +918,7 @@ sys_getpeername(struct proc *p, void *v, register_t *retval) error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0, p); if (error) goto bad; - if (len > m->m_len) - len = m->m_len; - error = copyout(mtod(m, caddr_t), SCARG(uap, asa), len); - if (error == 0) { -#ifdef KTRACE - if (KTRPOINT(p, KTR_STRUCT)) - ktrsockaddr(p, mtod(m, caddr_t), len); -#endif - error = copyout(&len, SCARG(uap, alen), sizeof (len)); - } + error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen)); bad: FRELE(fp, p); m_freem(m); @@ -1037,3 +1011,23 @@ sys_getrtable(struct proc *p, void *v, register_t *retval) *retval = (int)p->p_p->ps_rtableid; return (0); } + +int +copyaddrout(struct proc *p, struct mbuf *name, struct sockaddr *sa, + socklen_t buflen, socklen_t *outlen) +{ + int error; + socklen_t namelen = name->m_len; + + /* SHOULD COPY OUT A CHAIN HERE */ + error = copyout(mtod(name, caddr_t), sa, MIN(buflen, namelen)); + if (error == 0) { +#ifdef KTRACE + if (KTRPOINT(p, KTR_STRUCT)) + ktrsockaddr(p, mtod(name, caddr_t), namelen); +#endif + error = copyout(&namelen, outlen, sizeof(*outlen)); + } + + return (error); +} |