From 1838e64b62a28ee2cf4408baca983f68ab67afdf Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 7 Nov 2001 20:33:55 +0000 Subject: MFC 1.30: Force length of sockaddr to match family. --- sys/compat/linux/linux_socket.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'sys/compat/linux/linux_socket.c') diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index ac73ddeb0c85..986fc8a31f61 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -54,6 +54,27 @@ #include #include +/* + * FreeBSD's socket calls require the sockaddr struct length to agree + * with the address family. Linux does not, so we must force it. + */ +static int +linux_to_bsd_namelen(caddr_t name, int namelen) +{ + uint16_t family; /* XXX must match Linux sockaddr */ + + if (copyin(name, &family, sizeof(family))) + return namelen; + + switch (family) { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + } + return namelen; +} + #ifndef __alpha__ static int linux_to_bsd_domain(int domain) @@ -373,7 +394,8 @@ linux_bind(struct proc *p, struct linux_bind_args *args) bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; - bsd_args.namelen = linux_args.namelen; + bsd_args.namelen = linux_to_bsd_namelen(bsd_args.name, + linux_args.namelen); return (bind(p, &bsd_args)); } @@ -407,7 +429,8 @@ linux_connect(struct proc *p, struct linux_connect_args *args) bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; - bsd_args.namelen = linux_args.namelen; + bsd_args.namelen = linux_to_bsd_namelen(bsd_args.name, + linux_args.namelen); error = connect(p, &bsd_args); if (error != EISCONN) return (error); -- cgit v1.3