On Mon, 30 Jan 2012 22:49:22 +0900 (JST)
YASUOKA Masahiko <yasu...@yasuoka.net> wrote:
> pipex hook in udp_usrreq() mistakenly assumed that `inp' is
> connected.  The hook could not use the destination address properly,
> so it failed to find the pipex session.  This bug caused LCP keepalive
> failures on L2TP from client that does LCP keepalive and uses sequence
> number on the L2TP data channel (xl2tpd + pppd).
> 
> The diff includes kernel header file changes.
> 
> ok?

Oops.  Let me update the diff.

The given struct sockaddr object of
pipex_l2tp_userland_lookup_session() became passed from the userland,
so its address family must be checked.

ok?

Index: sys/net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.25
diff -u -p -r1.25 pipex.c
--- sys/net/pipex.c     23 Jan 2012 03:36:21 -0000      1.25
+++ sys/net/pipex.c     30 Jan 2012 14:37:31 -0000
@@ -2210,13 +2210,16 @@ pipex_l2tp_userland_lookup_session_ipv6(
 }
 #endif
 
-Static struct pipex_session *
+struct pipex_session *
 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
 {
        struct pipex_l2tp_header l2tp;
        struct pipex_hash_head *list;
        struct pipex_session *session;
        uint16_t session_id, tunnel_id, flags;
+
+       if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
+               return (NULL);
 
        /* pullup */
        if (m0->m_pkthdr.len < sizeof(l2tp)) {
Index: sys/net/pipex.h
===================================================================
RCS file: /cvs/src/sys/net/pipex.h,v
retrieving revision 1.11
diff -u -p -r1.11 pipex.h
--- sys/net/pipex.h     23 Jan 2012 03:36:21 -0000      1.11
+++ sys/net/pipex.h     30 Jan 2012 14:37:31 -0000
@@ -210,6 +210,7 @@ struct pipex_session  *pipex_pptp_lookup
 struct mbuf           *pipex_pptp_input (struct mbuf *, struct pipex_session 
*);
 struct pipex_session  *pipex_pptp_userland_lookup_session_ipv4 (struct mbuf *, 
struct in_addr);
 struct pipex_session  *pipex_pptp_userland_lookup_session_ipv6 (struct mbuf *, 
struct in6_addr);
+struct pipex_session  *pipex_l2tp_userland_lookup_session(struct mbuf *, 
struct sockaddr *);
 struct mbuf           *pipex_pptp_userland_output (struct mbuf *, struct 
pipex_session *);
 struct pipex_session  *pipex_l2tp_lookup_session (struct mbuf *, int);
 struct mbuf           *pipex_l2tp_input (struct mbuf *, int off, struct 
pipex_session *);
Index: sys/net/pipex_local.h
===================================================================
RCS file: /cvs/src/sys/net/pipex_local.h,v
retrieving revision 1.14
diff -u -p -r1.14 pipex_local.h
--- sys/net/pipex_local.h       25 Nov 2011 13:05:06 -0000      1.14
+++ sys/net/pipex_local.h       30 Jan 2012 14:37:31 -0000
@@ -406,7 +406,6 @@ Static struct pipex_session  *pipex_pptp
 
 #ifdef PIPEX_L2TP
 Static void                  pipex_l2tp_output (struct mbuf *, struct 
pipex_session *);
-Static struct pipex_session  *pipex_l2tp_userland_lookup_session(struct mbuf 
*, struct sockaddr *);
 #endif
 
 #ifdef PIPEX_MPPE
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.145
diff -u -p -r1.145 udp_usrreq.c
--- sys/netinet/udp_usrreq.c    8 Jul 2011 18:30:17 -0000       1.145
+++ sys/netinet/udp_usrreq.c    30 Jan 2012 14:37:32 -0000
@@ -1198,6 +1198,12 @@ udp_usrreq(struct socket *so, int req, s
 #ifdef PIPEX
                if (inp->inp_pipex) {
                        struct pipex_session *session;
+
+                       if (addr != NULL) 
+                               session =
+                                   pipex_l2tp_userland_lookup_session(m,
+                                       mtod(addr, struct sockaddr *));
+                       else
 #ifdef INET6
                        if (inp->inp_flags & INP_IPV6)
                                session =

Reply via email to