[prev in list] [next in list] [prev in thread] [next in thread]
List: openbsd-tech
Subject: Fix accept/recv/getsockname/etc to return the full addr length
From: Matthew Dempsky <matthew () dempsky ! org>
Date: 2012-04-25 22:42:33
Message-ID: 20120425224233.GA6118 () mdempsky ! mtv ! corp ! google ! com
[Download RAW message or body]
According to POSIX, accept(), recvfrom(), recvmsg(), getsockname(),
and getpeername() are supposed to store the untruncated address length
in *addrlen.
Diff below makes our methods conform to this requirement and also
cleans things up a little bit by refactoring out some common code into
a new copyaddrout() function.
ok?
Index: uipc_syscalls.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.84
diff -u -p -r1.84 uipc_syscalls.c
--- uipc_syscalls.c 3 Dec 2011 12:38:30 -0000 1.84
+++ uipc_syscalls.c 20 Apr 2012 22:10:04 -0000
@@ -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, regist
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, regi
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 msg
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,
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);
if (m)
@@ -935,16 +918,7 @@ sys_getpeername(struct proc *p, void *v,
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);
m_freem(m);
@@ -1036,4 +1010,24 @@ sys_getrtable(struct proc *p, void *v, r
{
*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);
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic