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