diff options
| author | Marcel Moolenaar <marcel@FreeBSD.org> | 2001-11-07 20:33:55 +0000 |
|---|---|---|
| committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2001-11-07 20:33:55 +0000 |
| commit | 1838e64b62a28ee2cf4408baca983f68ab67afdf (patch) | |
| tree | 490bd62b5b59ba860da9a37969a662c168bb40ab /sys/compat/linux/linux_socket.c | |
| parent | 39a15b50f2746fa1eaefdb0f9633b22fdc2496ca (diff) | |
Notes
Diffstat (limited to 'sys/compat/linux/linux_socket.c')
| -rw-r--r-- | sys/compat/linux/linux_socket.c | 27 |
1 files changed, 25 insertions, 2 deletions
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 <compat/linux/linux_socket.h> #include <compat/linux/linux_util.h> +/* + * 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); |
