NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/44418: FAST_IPSEC and if_wm kernel panic - may affect the whole network stack



The following reply was made to PR kern/44418; it has been noted by GNATS.

From: Wolfgang Stukenbrock <Wolfgang.Stukenbrock%nagler-company.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: Wolfgang.Stukenbrock%nagler-company.com@localhost
Subject: Re: kern/44418: FAST_IPSEC and if_wm kernel panic - may affect the 
whole network stack
Date: Thu, 20 Jan 2011 14:15:25 +0100

 Hi again,
 
 I've done some further analyses and detect that the major difference
 between the 4.0 and 5.x implementation is the softnet_lock mutex.
 
 It looks like someone has missed to add this to then path from the 
 crypto-callback into the network stack in xform_ah.c, xform_esp.c and 
 xform_ipcomp.c.
 
 I've added the mutex_enter/mutex_exit after/before the 
 splsoftnet()/splx() in this tree files and the problem in the FAST_IPSEC 
 parts seems to be fixed.
 
 By the way: in xform_ah.c there was a missing splx() when reentering a 
 crypto request. This is fixed in the patches below too.
 
 
 At the moment I've still a problem in the wm-driver with NULL mbuf in 
 wm_start(), but I'm gooing to look at that separately.
 Perhaps it is related to some obsolete debugging code from my tests .... 
 I need to reinstall the system to validate this.
 Perhaps somewhere else there is some locking on softnet_lock missing too.
 
 
 If the patches below are integrated in 5.x and HEAD, I think this PR can 
 be closed.
 I think this PR is still "critical", because FAST_IPSEC in 5.x and HEAD 
 is broken and cannot be used without blowing up the kernel.
 
 Best regards
 W. Stukenbrock
 
 Here the three patches that solves the problem:
 
 diff -u -r1.1 xform_ah.c
 --- xform_ah.c  2011/01/20 12:10:56     1.1
 +++ xform_ah.c  2011/01/20 12:13:53
 @@ -54,6 +54,8 @@
   #include <sys/kernel.h>
   #include <sys/sysctl.h>
 
 +#include <sys/socketvar.h>
 +
   #include <net/if.h>
 
   #include <netinet/in.h>
 @@ -829,6 +831,7 @@
   #endif
 
          s = splsoftnet();
 +       mutex_enter(softnet_lock);
 
          sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, sport, 
 dport);
          if (sav == NULL) {
 @@ -851,8 +854,11 @@
                  if (sav->tdb_cryptoid != 0)
                          sav->tdb_cryptoid = crp->crp_sid;
 
 -               if (crp->crp_etype == EAGAIN)
 +               if (crp->crp_etype == EAGAIN) {
 +                       mutex_exit(softnet_lock);
 +                       splx(s);
                          return crypto_dispatch(crp);
 +               }
 
                  AH_STATINC(AH_STAT_NOXFORM);
                  DPRINTF(("ah_input_cb: crypto error %d\n", 
 crp->crp_etype));
 @@ -959,11 +965,13 @@
          IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
 
          KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          return error;
   bad:
          if (sav)
                  KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          if (m != NULL)
                  m_freem(m);
 @@ -1247,6 +1255,7 @@
 
                  if (crp->crp_etype == EAGAIN) {
                          KEY_FREESAV(&sav);
 +                       mutex_exit(softnet_lock);
                          splx(s);
                          return crypto_dispatch(crp);
                  }
 @@ -1293,11 +1302,13 @@
          /* NB: m is reclaimed by ipsec_process_done. */
          err = ipsec_process_done(m, isr);
          KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          return err;
   bad:
          if (sav)
                  KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          if (m)
                  m_freem(m);
 
 
 diff -u -r1.1 xform_esp.c
 --- xform_esp.c 2011/01/20 12:14:23     1.1
 +++ xform_esp.c 2011/01/20 12:32:25
 @@ -55,6 +55,8 @@
   /*#include <sys/random.h>*/
   #include <sys/sysctl.h>
 
 +#include <sys/socketvar.h>
 +
   #include <net/if.h>
 
   #include <netinet/in.h>
 @@ -498,6 +500,7 @@
   #endif
 
          s = splsoftnet();
 +       mutex_enter(softnet_lock);
 
          sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, sport, 
   port);
          if (sav == NULL) {
 @@ -526,6 +529,7 @@
 
                  if (crp->crp_etype == EAGAIN) {
                          KEY_FREESAV(&sav);
 +                       mutex_exit(softnet_lock);
                          splx(s);
                          return crypto_dispatch(crp);
                  }
 @@ -664,11 +668,13 @@
          IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
 
          KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          return error;
   bad:
          if (sav)
                  KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          if (m != NULL)
                  m_freem(m);
 @@ -935,6 +941,7 @@
          m = (struct mbuf *) crp->crp_buf;
 
          s = splsoftnet();
 +       mutex_enter(softnet_lock);
 
          isr = tc->tc_isr;
          sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
 @@ -957,6 +964,7 @@
 
                  if (crp->crp_etype == EAGAIN) {
                          KEY_FREESAV(&sav);
 +                       mutex_exit(softnet_lock);
                          splx(s);
                          return crypto_dispatch(crp);
                  }
 @@ -1003,11 +1011,13 @@
          /* NB: m is reclaimed by ipsec_process_done. */
          err = ipsec_process_done(m, isr);
          KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          return err;
   bad:
          if (sav)
                  KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          if (m)
                  m_freem(m);
 
 
 diff -u -r1.2 xform_ipcomp.c
 --- xform_ipcomp.c      2010/05/04 13:53:23     1.2
 +++ xform_ipcomp.c      2011/01/20 12:12:15
 @@ -46,6 +46,8 @@
   #include <sys/protosw.h>
   #include <sys/sysctl.h>
 
 +#include <sys/socketvar.h>
 +
   #include <netinet/in.h>
   #include <netinet/in_systm.h>
   #include <netinet/ip.h>
 @@ -258,6 +260,7 @@
   #endif
 
          s = splsoftnet();
 +       mutex_enter(softnet_lock);
 
          sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, sport, 
 dport);
          if (sav == NULL) {
 @@ -281,6 +284,7 @@
 
                  if (crp->crp_etype == EAGAIN) {
                          KEY_FREESAV(&sav);
 +                       mutex_exit(softnet_lock);
                          splx(s);
                          return crypto_dispatch(crp);
                  }
 @@ -338,11 +342,13 @@
          IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, NULL);
 
          KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          return error;
   bad:
          if (sav)
                  KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          if (m)
                  m_freem(m);
 @@ -513,6 +519,7 @@
          rlen = crp->crp_ilen - skip;
 
          s = splsoftnet();
 +       mutex_enter(softnet_lock);
 
          isr = tc->tc_isr;
          sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
 @@ -532,6 +539,7 @@
 
                  if (crp->crp_etype == EAGAIN) {
                          KEY_FREESAV(&sav);
 +                       mutex_exit(softnet_lock);
                          splx(s);
                          return crypto_dispatch(crp);
                  }
 @@ -627,11 +635,13 @@
          /* NB: m is reclaimed by ipsec_process_done. */
          error = ipsec_process_done(m, isr);
          KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          return error;
   bad:
          if (sav)
                  KEY_FREESAV(&sav);
 +       mutex_exit(softnet_lock);
          splx(s);
          if (m)
                  m_freem(m);
 
 
 gnats-admin%NetBSD.org@localhost wrote:
 
 > Thank you very much for your problem report.
 > It has the internal identification `kern/44418'.
 > The individual assigned to look at your
 > report is: kern-bug-people. 
 > 
 > 
 >>Category:       kern
 >>Responsible:    kern-bug-people
 >>Synopsis:       FAST_IPSEC and if_wm kernel panic - may affect the whole 
 >>network stack
 >>Arrival-Date:   Wed Jan 19 18:55:00 +0000 2011
 >>
 > 
 
 
 -- 
 
 
 Dr. Nagler & Company GmbH
 Hauptstraße 9
 92253 Schnaittenbach
 
 Tel. +49 9622/71 97-42
 Fax +49 9622/71 97-50
 
 Wolfgang.Stukenbrock%nagler-company.com@localhost
 http://www.nagler-company.com
 
 
 Hauptsitz: Schnaittenbach
 Handelregister: Amberg HRB
 Gerichtsstand: Amberg
 Steuernummer: 201/118/51825
 USt.-ID-Nummer: DE 273143997
 Geschäftsführer: Dr. Martin Nagler, Dr. Dr. Karl-Kuno Kunze
 
 


Home | Main Index | Thread Index | Old Index