There is no need for the stackgap in sys_bind() and sys_connect().
If sa_len is zero, believing the size passed to bind/connect seems better than trying to strlen somthing that might run off the mapped kma. Verify the address family against the array size before indexing.
This commit is contained in:
parent
cf80941288
commit
4147586696
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: darwin_socket.c,v 1.13 2007/03/04 06:01:14 christos Exp $ */
|
/* $NetBSD: darwin_socket.c,v 1.14 2007/06/17 21:30:11 dsl Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: darwin_socket.c,v 1.13 2007/03/04 06:01:14 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: darwin_socket.c,v 1.14 2007/06/17 21:30:11 dsl Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -47,7 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: darwin_socket.c,v 1.13 2007/03/04 06:01:14 christos
|
||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/ucred.h>
|
#include <sys/ucred.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mbuf.h>
|
||||||
#include <sys/syscallargs.h>
|
#include <sys/syscallargs.h>
|
||||||
|
|
||||||
#include <compat/sys/signal.h>
|
#include <compat/sys/signal.h>
|
||||||
|
@ -160,6 +160,28 @@ native_to_darwin_sockaddr(nsa, dsa)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
fixup_darwin_sockaddr(struct mbuf *nam)
|
||||||
|
{
|
||||||
|
struct sockaddr *sa = mtod(nam, void *);
|
||||||
|
|
||||||
|
if ((unsigned)sa->sa_family >= __arraycount(darwin_to_native_af))
|
||||||
|
return EPROTONOSUPPORT;
|
||||||
|
sa->sa_family = darwin_to_native_af[sa->sa_family];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sa_len is zero for AF_LOCAL sockets, believe size we copied in!
|
||||||
|
* The code used to strlen the filename, but that way lies madness!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (sa->sa_len > nam->m_len || sa->sa_len == 0)
|
||||||
|
sa->sa_len = nam->m_len;
|
||||||
|
else
|
||||||
|
nam->m_len = sa->sa_len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
darwin_to_native_sockaddr(dsa, nsa)
|
darwin_to_native_sockaddr(dsa, nsa)
|
||||||
struct sockaddr *dsa;
|
struct sockaddr *dsa;
|
||||||
|
@ -200,6 +222,9 @@ darwin_to_native_sockaddr(dsa, nsa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((unsigned)dsa->sa_family >= __arraycount(darwin_to_native_af))
|
||||||
|
return EPROTONOSUPPORT;
|
||||||
|
|
||||||
memcpy(nsa, dsa, len);
|
memcpy(nsa, dsa, len);
|
||||||
/* Array dereference is safe. sa_family is type unsigned */
|
/* Array dereference is safe. sa_family is type unsigned */
|
||||||
nsa->ss_family = darwin_to_native_af[dsa->sa_family];
|
nsa->ss_family = darwin_to_native_af[dsa->sa_family];
|
||||||
|
@ -220,7 +245,7 @@ darwin_sys_socket(l, v, retval)
|
||||||
} */ *uap = v;
|
} */ *uap = v;
|
||||||
struct compat_30_sys_socket_args cup;
|
struct compat_30_sys_socket_args cup;
|
||||||
|
|
||||||
if (SCARG(uap, domain) < 0)
|
if ((unsigned)SCARG(uap, domain) >= __arraycount(darwin_to_native_af))
|
||||||
return (EPROTONOSUPPORT);
|
return (EPROTONOSUPPORT);
|
||||||
|
|
||||||
SCARG(&cup, domain) = darwin_to_native_af[SCARG(uap, domain)];
|
SCARG(&cup, domain) = darwin_to_native_af[SCARG(uap, domain)];
|
||||||
|
@ -462,36 +487,17 @@ darwin_sys_connect(l, v, retval)
|
||||||
syscallarg(struct sockaddr *) name;
|
syscallarg(struct sockaddr *) name;
|
||||||
syscallarg(unsigned int *) namelen;
|
syscallarg(unsigned int *) namelen;
|
||||||
} */ *uap = v;
|
} */ *uap = v;
|
||||||
struct sys_connect_args cup;
|
struct mbuf *nam;
|
||||||
struct proc *p = l->l_proc;
|
|
||||||
void *sg = stackgap_init(p, 0);
|
|
||||||
struct sockaddr_storage nss;
|
|
||||||
struct sockaddr_storage dss;
|
|
||||||
struct sockaddr_storage *nssp;
|
|
||||||
size_t len;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
nssp = stackgap_alloc(p, &sg, sizeof(*nssp));
|
error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
|
||||||
|
MT_SONAME);
|
||||||
|
if (error == 0)
|
||||||
|
error = fixup_darwin_sockaddr(nam);
|
||||||
|
if (error == 0)
|
||||||
|
error = do_sys_connect(l, SCARG(uap, s), nam);
|
||||||
|
|
||||||
if ((error = copyin(SCARG(uap, name), &dss, sizeof(dss))) != 0)
|
return error;
|
||||||
return error;
|
|
||||||
|
|
||||||
if ((error = darwin_to_native_sockaddr((struct sockaddr *)&dss,
|
|
||||||
&nss)) != 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
len = SCARG(uap, namelen);
|
|
||||||
if (nss.ss_len < len)
|
|
||||||
len = nss.ss_len;
|
|
||||||
|
|
||||||
if ((error = copyout(&nss, nssp, sizeof(nss))) != 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
SCARG(&cup, s) = SCARG(uap, s);
|
|
||||||
SCARG(&cup, name) = (struct sockaddr *)nssp;
|
|
||||||
SCARG(&cup, namelen) = len;
|
|
||||||
|
|
||||||
return bsd_sys_connect(l, &cup, retval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -505,36 +511,17 @@ darwin_sys_bind(l, v, retval)
|
||||||
syscallarg(struct sockaddr *) name;
|
syscallarg(struct sockaddr *) name;
|
||||||
syscallarg(unsigned int *) namelen;
|
syscallarg(unsigned int *) namelen;
|
||||||
} */ *uap = v;
|
} */ *uap = v;
|
||||||
struct sys_bind_args cup;
|
struct mbuf *nam;
|
||||||
struct proc *p = l->l_proc;
|
|
||||||
void *sg = stackgap_init(p, 0);
|
|
||||||
struct sockaddr_storage nss;
|
|
||||||
struct sockaddr_storage dss;
|
|
||||||
struct sockaddr_storage *nssp;
|
|
||||||
size_t len;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
nssp = stackgap_alloc(p, &sg, sizeof(*nssp));
|
error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
|
||||||
|
MT_SONAME);
|
||||||
|
if (error == 0)
|
||||||
|
error = fixup_darwin_sockaddr(nam);
|
||||||
|
if (error == 0)
|
||||||
|
error = do_sys_bind(l, SCARG(uap, s), nam);
|
||||||
|
|
||||||
if ((error = copyin(SCARG(uap, name), &dss, sizeof(dss))) != 0)
|
return error;
|
||||||
return error;
|
|
||||||
|
|
||||||
if ((error = darwin_to_native_sockaddr((struct sockaddr *)&dss,
|
|
||||||
&nss)) != 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
len = SCARG(uap, namelen);
|
|
||||||
if (nss.ss_len < len)
|
|
||||||
len = nss.ss_len;
|
|
||||||
|
|
||||||
if ((error = copyout(&nss, nssp, sizeof(nss))) != 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
SCARG(&cup, s) = SCARG(uap, s);
|
|
||||||
SCARG(&cup, name) = (struct sockaddr *)nssp;
|
|
||||||
SCARG(&cup, namelen) = len;
|
|
||||||
|
|
||||||
return bsd_sys_bind(l, &cup, retval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue