Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/compat/linux/common if passed sockaddr has family AF_UNS...
details: https://anonhg.NetBSD.org/src/rev/2dbb635ab894
branches: trunk
changeset: 569897:2dbb635ab894
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sun Sep 12 15:32:55 2004 +0000
description:
if passed sockaddr has family AF_UNSPEC, use socket family of the socket
the sockaddr is used for
this fixes bind() problem in Linux version of Theocracy, testing
by Thomas Klausner
diffstat:
sys/compat/linux/common/linux_socket.c | 51 ++++++++++++++++++++++++++-------
1 files changed, 40 insertions(+), 11 deletions(-)
diffs (122 lines):
diff -r 38681cc32ba5 -r 2dbb635ab894 sys/compat/linux/common/linux_socket.c
--- a/sys/compat/linux/common/linux_socket.c Sun Sep 12 13:12:26 2004 +0000
+++ b/sys/compat/linux/common/linux_socket.c Sun Sep 12 15:32:55 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_socket.c,v 1.52 2004/09/05 09:38:17 jdolecek Exp $ */
+/* $NetBSD: linux_socket.c,v 1.53 2004/09/12 15:32:55 jdolecek Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.52 2004/09/05 09:38:17 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.53 2004/09/12 15:32:55 jdolecek Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -60,6 +60,7 @@
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/domain.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
@@ -114,8 +115,8 @@
int linux_to_bsd_tcp_sockopt __P((int));
int linux_to_bsd_udp_sockopt __P((int));
int linux_getifhwaddr __P((struct proc *, register_t *, u_int, void *));
-static int linux_sa_get __P((struct proc *, caddr_t *sgp, struct sockaddr **sap,
- const struct osockaddr *osa, int *osalen));
+static int linux_sa_get __P((struct proc *, int, caddr_t *, struct sockaddr **,
+ const struct osockaddr *, int *));
static int linux_sa_put __P((struct osockaddr *osa));
static int linux_to_bsd_msg_flags __P((int));
static int bsd_to_linux_msg_flags __P((int));
@@ -386,7 +387,9 @@
int error;
caddr_t sg = stackgap_init(p, 0);
- if ((error = linux_sa_get(p, &sg, &sa, SCARG(uap, to), &tolen)))
+ error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
+ SCARG(uap, to), &tolen);
+ if (error)
return (error);
SCARG(&bsa, to) = sa;
@@ -440,7 +443,7 @@
struct sockaddr *sa;
sg = stackgap_init(p, 0);
- error = linux_sa_get(p, &sg, &sa,
+ error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
(struct osockaddr *) msg.msg_name, &msg.msg_namelen);
if (error)
goto done;
@@ -1322,7 +1325,8 @@
int namlen;
namlen = SCARG(uap, namelen);
- error = linux_sa_get(p, &sg, &sa, SCARG(uap, name), &namlen);
+ error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
+ SCARG(uap, name), &namlen);
if (error)
return (error);
@@ -1381,7 +1385,8 @@
struct sockaddr *sa;
caddr_t sg = stackgap_init(p, 0);
- error = linux_sa_get(p, &sg, &sa, SCARG(uap, name), &namlen);
+ error = linux_sa_get(p, SCARG(uap, s), &sg, &sa,
+ SCARG(uap, name), &namlen);
if (error)
return (error);
@@ -1443,8 +1448,9 @@
* the converted structure there, address on stackgap returned in sap.
*/
static int
-linux_sa_get(p, sgp, sap, osa, osalen)
+linux_sa_get(p, s, sgp, sap, osa, osalen)
struct proc *p;
+ int s;
caddr_t *sgp;
struct sockaddr **sap;
const struct osockaddr *osa;
@@ -1520,8 +1526,31 @@
error = EINVAL;
goto out;
}
- } else
-#endif
+ }
+#endif
+
+ /*
+ * If the family is unspecified, use address family of the
+ * socket. This avoid triggering COMPAT_43 struct socket family check
+ * in sockargs() on little-endian machines, and strict family checks
+ * in netinet/in_pcb.c et.al.
+ */
+ if (bdom == AF_UNSPEC) {
+ struct file *fp;
+ struct socket *so;
+
+ /* getsock() will use the descriptor for us */
+ if ((error = getsock(p->p_fd, s, &fp)) != 0)
+ goto out;
+
+ so = (struct socket *)fp->f_data;
+ bdom = so->so_proto->pr_domain->dom_family;
+
+ FILE_UNUSE(fp, p);
+
+ DPRINTF(("AF_UNSPEC family adjusted to %d\n", bdom));
+ }
+
if (bdom == AF_INET) {
alloclen = sizeof(struct sockaddr_in);
}
Home |
Main Index |
Thread Index |
Old Index