NetBSD Problem Report #37037
From stix@stix.id.au Sat Sep 29 10:10:03 2007
Return-Path: <stix@stix.id.au>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by narn.NetBSD.org (Postfix) with ESMTP id E938863B8C2
for <gnats-bugs@gnats.NetBSD.org>; Sat, 29 Sep 2007 10:10:02 +0000 (UTC)
Message-Id: <20070929101000.EB8CC67F9B@stix.id.au>
Date: Sat, 29 Sep 2007 20:10:00 +1000 (EST)
From: Paul@stix.id.au, Ripke@stix.id.au
Reply-To: stix@stix.id.au
To: gnats-bugs@NetBSD.org
Subject: ipnat: Data modified on freelist
X-Send-Pr-Version: 3.95
>Number: 37037
>Category: kern
>Synopsis: ipnat: Data modified on freelist
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: kern-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Sep 29 10:15:00 +0000 2007
>Closed-Date: Sun Oct 14 00:51:15 +0000 2007
>Last-Modified: Tue Nov 13 01:30:01 +0000 2007
>Originator: Paul Ripke
>Release: NetBSD 4.0_RC1
>Organization:
>Environment:
System: NetBSD zion.stix.org.au 4.0_RC1 NetBSD 4.0_RC1 (ZION) #1: Fri Sep 28 09:46:22 EST 2007 stix@hex.stix.org.au:/l/netbsd/netbsd-4/obj.i386/l/netbsd/netbsd-4/src/sys/arch/i386/compile/ZION i386
CVS update as of around 2007/09/28
$NetBSD: ip_state.c,v 1.15.2.8 2007/09/27 14:01:10 xtraeme Exp $
Architecture: i386
Machine: i386
>Description:
"ipnat -l" causing:
Sep 29 19:17:03 zion sudo: stix : TTY=ttyp2 ; PWD=/export/home/stix ; USER=root ; COMMAND=/usr/sbin/ipnat -l
Sep 29 19:17:13 zion /netbsd: Data modified on freelist: word 3 of object 0xc1df2080 size 36 previous type bar (0xc1e0f200 != 0xdeadbeef)
Sep 29 19:17:43 zion /netbsd: Data modified on freelist: word 3 of object 0xc1dbfdc0 size 36 previous type bar (0xc1f51e00 != 0xdeadbeef)
Possibly due to RDR sessions not expiring:
ksh$ sudo ipnat -l | grep RDR | wc -l
2168
ksh$ sudo ./ipnat -s
mapped in 77822 out 125346
added 3125 expired 944
no memory 0 bad nat 224
inuse 2181
rules 4
wilds 0
table 0xbfbfe95c list 0xc1e0f800
TCP Entries per state
0 1 2 3 4 5 6 7 8 9 10 11
0 0 0 0 2179 0 0 0 0 0 0 0
>How-To-Repeat:
/etc/ipnat.conf:
map pppoe0 192.168.0.0/16 -> 0/32 portmap tcp/udp 49152:65535 mssclamp 1440
map pppoe0 192.168.0.0/16 -> 0/32 mssclamp 1440
rdr ath0 0.0.0.0/0 port 80 -> 127.0.0.1 port 3128 tcp
rdr sk0 0.0.0.0/0 port 80 -> 127.0.0.1 port 3128 tcp
>Fix:
Unknown.
>Release-Note:
>Audit-Trail:
From: Michael van Elst <mlelstv@serpens.de>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/37037: ipnat: Data modified on freelist
Date: Sat, 29 Sep 2007 13:14:00 +0200
One more data point:
the same also occurs on a NetBSD 4.0_RC1 kernel built on Sep 1.
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: Darren Reed <darrenr@netbsd.org>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/37037
Date: Sat, 29 Sep 2007 05:30:20 -0700
In 4.0RC1, the code is:
5057: case IPFGENITER_NAT :
5058: if (nextnat != NULL) {
5059: if (nextnat->nat_next == NULL) {
5060: count = 1;
5061: freet = t;
5062: nat = NULL;
5063: }
5064: if (count == 1) {
5065:
MUTEX_ENTER(&nextnat->nat_lock);
5066: nextnat->nat_ref++;
5067:
MUTEX_EXIT(&nextnat->nat_lock);
5068: }
5069: } else {
5070: bzero(&zeronat, sizeof(zeronat));
5071: nextnat = &zeronat;
5072: count = 1;
5073: }
5074: break;
5075: default :
5076: break;
5077: }
5078: RWLOCK_EXIT(&ipf_nat);
5079:
5080: if (freet != NULL) {
5081: ipf_freetoken(freet);
5082: freet = NULL;
5083: }
...
5112: case IPFGENITER_NAT :
5113: if (nat != NULL)
5114: fr_natderef(&nat);
5115: t->ipt_data = nextnat;
5116: error = COPYOUT(nextnat, dst,
sizeof(*nextnat));
...
Sofor the case when nextnat->nat_next == NULL, count gets set to 1,
freet is assigned the value of t, that structure is freed and then on 5115
it is deref'd again (memory use after free.)
Darren
From: Martti Kuparinen <martti.kuparinen@iki.fi>
To: gnats-bugs@netbsd.org
Cc: juan@xtrarom.org, darrenr@netbsd.org
Subject: Re: kern/37037
Date: Sat, 29 Sep 2007 21:37:22 +0300 (EEST)
After some help from Darren, I created this patch? Does it help?
Darren: does it look correct? I took 4.1.27 and added our local changes
to it (caddr_t -> void * etc.)
Index: ip_frag.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_frag.c,v
retrieving revision 1.7
diff -u -r1.7 ip_frag.c
--- ip_frag.c 16 Jun 2007 10:52:28 -0000 1.7
+++ ip_frag.c 29 Sep 2007 18:29:12 -0000
@@ -106,7 +106,7 @@
__KERNEL_RCSID(0, "$NetBSD: ip_frag.c,v 1.7 2007/06/16 10:52:28 martin Exp $");
#else
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77.2.9 2007/05/27 11:13:44 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77.2.12 2007/09/20 12:51:51 darrenr Exp $";
#endif
#endif
@@ -943,16 +943,16 @@
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(lock);
if (frag != NULL) {
- WRITE_ENTER(lock);
- frag->ipfr_ref--;
- if (frag->ipfr_ref <= 0)
- fr_fragfree(frag);
- RWLOCK_EXIT(lock);
+#ifdef USE_MUTEXES
+ fr_fragderef(&frag, lock);
+#else
+ fr_fragderef(&frag);
+#endif
}
error = COPYOUT(next, itp->igi_data, sizeof(*next));
Index: ip_state.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_state.c,v
retrieving revision 1.29
diff -u -r1.29 ip_state.c
--- ip_state.c 17 Sep 2007 06:56:15 -0000 1.29
+++ ip_state.c 29 Sep 2007 18:29:15 -0000
@@ -117,7 +117,7 @@
__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.29 2007/09/17 06:56:15 martti Exp $");
#else
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_state.c,v 2.186.2.69 2007/05/26 13:05:14 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.78 2007/09/20 12:51:53 darrenr Exp $";
#endif
#endif
@@ -657,8 +657,8 @@
int error;
error = fr_inobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
+ if (error != 0)
+ return error;
isn = ips.ips_next;
if (isn == NULL) {
@@ -687,9 +687,7 @@
bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
sizeof(ips.ips_fr));
error = fr_outobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
- return 0;
+ return error;
}
@@ -1444,7 +1442,7 @@
is->is_state[!source] = IPF_TCPS_CLOSED;
fr_movequeue(&is->is_sti, is->is_sti.tqe_ifq,
&ips_deletetq);
- MUTEX_ENTER(&is->is_lock);
+ MUTEX_EXIT(&is->is_lock);
return 0;
}
}
@@ -2308,8 +2306,6 @@
ipstate_t **isp;
u_int hvm;
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
hvm = is->is_hv;
/*
* Remove the hash from the old location...
@@ -2897,8 +2893,6 @@
int why;
{
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
/*
* Since we want to delete this, remove it from the state table,
* where it can be found & used, first.
@@ -4072,7 +4066,7 @@
if (itp->igi_data == NULL)
return EFAULT;
- if (itp->igi_nitems == 0)
+ if (itp->igi_nitems < 1)
return ENOSPC;
if (itp->igi_type != IPFGENITER_STATE)
@@ -4094,33 +4088,29 @@
next = is->is_next;
}
- for (count = itp->igi_nitems; count > 0; count--) {
+ count = itp->igi_nitems;
+ for (;;) {
if (next != NULL) {
/*
* If we find a state entry to use, bump its
* reference count so that it can be used for
* is_next when we come back.
*/
- MUTEX_ENTER(&next->is_lock);
- next->is_ref++;
- MUTEX_EXIT(&next->is_lock);
- token->ipt_data = next;
+ if (count == 1) {
+ MUTEX_ENTER(&next->is_lock);
+ next->is_ref++;
+ MUTEX_EXIT(&next->is_lock);
+ token->ipt_data = next;
+ }
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
count = 1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(&ipf_state);
/*
- * If we had a prior pointer to a state entry, release it.
- */
- if (is != NULL) {
- fr_statederef(&is);
- }
-
- /*
* This should arguably be via fr_outobj() so that the state
* structure can (if required) be massaged going out.
*/
@@ -4131,9 +4121,14 @@
break;
dst += sizeof(*next);
+ count--;
+
READ_ENTER(&ipf_state);
- is = next;
- next = is->is_next;
+ next = next->is_next;
+ }
+
+ if (is != NULL) {
+ fr_statederef(&is);
}
return error;
From: Darren Reed <darrenr@netbsd.org>
To: Martti Kuparinen <martti.kuparinen@iki.fi>
Cc: gnats-bugs@netbsd.org, juan@xtrarom.org
Subject: Re: kern/37037
Date: Sat, 29 Sep 2007 13:51:07 -0700
Martti Kuparinen wrote:
> After some help from Darren, I created this patch? Does it help?
You did not include the changes to ip_nat.c in this, which are vital.
> Darren: does it look correct? I took 4.1.27 and added our local changes
> to it (caddr_t -> void * etc.)
What is there looks correct.
Darren
From: Martti Kuparinen <martti.kuparinen@iki.fi>
To: darrenr@netbsd.org
Cc: gnats-bugs@netbsd.org, juan@xtrarom.org
Subject: Re: kern/37037
Date: Sun, 30 Sep 2007 10:03:02 +0300
Darren Reed wrote:
> You did not include the changes to ip_nat.c in this, which are vital.
Oh, you didn't tell me that this file is also needed (you told me only
about ip_state.c and ip_frag.c). This new ip_nat.c needs the new
ip_fil.h and I'm losing the track here with all these changes.
Could you please provide a patch which contains only the required changes?
Martti
From: Martti Kuparinen <martti.kuparinen@iki.fi>
To: Darren Reed <darrenr@netbsd.org>
Cc: gnats-bugs@netbsd.org, juan@xtrarom.org
Subject: Re: kern/37037
Date: Sun, 30 Sep 2007 10:15:28 +0300 (EEST)
Could you please try this patch (also at http://users.piuha.net/martti/tmp/p)
Martti
Index: ip_fil.h
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_fil.h,v
retrieving revision 1.14
diff -u -r1.14 ip_fil.h
--- ip_fil.h 19 Jul 2007 14:04:34 -0000 1.14
+++ ip_fil.h 30 Sep 2007 07:10:15 -0000
@@ -184,14 +184,14 @@
HI63(a) < HI63(b)))))))
#define NLADD(n,x) htonl(ntohl(n) + (x))
#define IP6_INC(a) \
- { i6addr_t *_i6 = (i6addr_t *)(a); \
- _i6->i6[0] = NLADD(_i6->i6[0], 1); \
- if (_i6->i6[0] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[1], 1); \
- if (_i6->i6[1] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[2], 1); \
- if (_i6->i6[2] == 0) { \
- _i6->i6[0] = NLADD(_i6->i6[3], 1); \
+ { u_32_t *_i6 = (u_32_t *)(a); \
+ _i6[3] = NLADD(_i6[3], 1); \
+ if (_i6[3] == 0) { \
+ _i6[2] = NLADD(_i6[2], 1); \
+ if (_i6[2] == 0) { \
+ _i6[1] = NLADD(_i6[1], 1); \
+ if (_i6[1] == 0) { \
+ _i6[0] = NLADD(_i6[0], 1); \
} \
} \
} \
@@ -270,6 +270,7 @@
#define FI_WITH 0xeffe /* Not FI_TCPUDP */
#define FI_V6EXTHDR 0x10000
#define FI_COALESCE 0x20000
+#define FI_NEWNAT 0x40000
#define FI_NOCKSUM 0x20000000 /* don't do a L4 checksum validation */
#define FI_DONTCACHE 0x40000000 /* don't cache the result */
#define FI_IGNORE 0x80000000
@@ -329,6 +330,7 @@
u_short fin_off;
int fin_depth; /* Group nesting depth */
int fin_error; /* Error code to return */
+ int fin_cksum; /* -1 bad, 1 good, 0 not done */
void *fin_nat;
void *fin_state;
void *fin_nattag;
@@ -1203,6 +1205,8 @@
} ipftable_t;
#define IPFTABLE_BUCKETS 1
+#define IPFTABLE_BUCKETS_NATIN 2
+#define IPFTABLE_BUCKETS_NATOUT 3
/*
@@ -1402,6 +1406,13 @@
# endif /* __ sgi */
# endif /* MENTAT */
+# if defined(__FreeBSD_version)
+extern int ipf_pfil_hook __P((void));
+extern int ipf_pfil_unhook __P((void));
+extern void ipf_event_reg __P((void));
+extern void ipf_event_dereg __P((void));
+# endif
+
#endif /* #ifndef _KERNEL */
extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap;
Index: ip_frag.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_frag.c,v
retrieving revision 1.7
diff -u -r1.7 ip_frag.c
--- ip_frag.c 16 Jun 2007 10:52:28 -0000 1.7
+++ ip_frag.c 30 Sep 2007 07:10:15 -0000
@@ -106,7 +106,7 @@
__KERNEL_RCSID(0, "$NetBSD: ip_frag.c,v 1.7 2007/06/16 10:52:28 martin Exp $");
#else
static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77.2.9 2007/05/27 11:13:44 darrenr Exp";
+static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77.2.12 2007/09/20 12:51:51 darrenr Exp $";
#endif
#endif
@@ -943,16 +943,16 @@
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(lock);
if (frag != NULL) {
- WRITE_ENTER(lock);
- frag->ipfr_ref--;
- if (frag->ipfr_ref <= 0)
- fr_fragfree(frag);
- RWLOCK_EXIT(lock);
+#ifdef USE_MUTEXES
+ fr_fragderef(&frag, lock);
+#else
+ fr_fragderef(&frag);
+#endif
}
error = COPYOUT(next, itp->igi_data, sizeof(*next));
Index: ip_nat.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_nat.c,v
retrieving revision 1.32
diff -u -r1.32 ip_nat.c
--- ip_nat.c 14 Sep 2007 11:28:45 -0000 1.32
+++ ip_nat.c 30 Sep 2007 07:10:19 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_nat.c,v 1.32 2007/09/14 11:28:45 martti Exp $ */
+/* $NetBSD: ip_nat.c,v 1.1.1.9 2007/06/16 10:33:21 martin Exp $ */
/*
* Copyright (C) 1995-2003 by Darren Reed.
@@ -16,12 +16,13 @@
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
-#if (__NetBSD_Version__ >= 399002000) && defined(_KERNEL)
+#if defined(_KERNEL) && defined(__NetBSD_Version__) && \
+ (__NetBSD_Version__ >= 399002000)
# include <sys/kauth.h>
#endif
#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
defined(_KERNEL)
-# if (__NetBSD_Version__ < 399001400)
+#if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 399001400)
# include "opt_ipfilter_log.h"
# else
# include "opt_ipfilter.h"
@@ -116,7 +117,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.87 2007/05/31 10:17:17 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.100 2007/09/25 08:27:31 darrenr Exp $";
#endif
@@ -177,7 +178,7 @@
natstat_t nat_stats;
int fr_nat_lock = 0;
int fr_nat_init = 0;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
extern int pfil_delayed_copy;
#endif
@@ -186,13 +187,13 @@
static int nat_clearlist __P((void));
static void nat_addnat __P((struct ipnat *));
static void nat_addrdr __P((struct ipnat *));
-static void nat_delete __P((struct nat *, int));
static void nat_delrdr __P((struct ipnat *));
static void nat_delnat __P((struct ipnat *));
static int fr_natgetent __P((caddr_t));
static int fr_natgetsz __P((caddr_t));
static int fr_natputent __P((caddr_t, int));
static int nat_extraflush __P((int));
+static int nat_gettable __P((char *));
static void nat_tabmove __P((nat_t *));
static int nat_match __P((fr_info_t *, ipnat_t *));
static INLINE int nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *));
@@ -652,7 +653,7 @@
SPL_INT(s);
#if (BSD >= 199306) && defined(_KERNEL)
-# if (__NetBSD_Version__ >= 399002000)
+# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 399002000)
if ((mode & FWRITE) &&
kauth_authorize_network(curlwp->l_cred, KAUTH_NETWORK_FIREWALL,
KAUTH_REQ_NETWORK_FIREWALL_FW,
@@ -943,6 +944,10 @@
error = fr_outobj(data, nat_tqb, IPFOBJ_STATETQTAB);
break;
+ case SIOCGTABL :
+ error = nat_gettable(data);
+ break;
+
default :
error = EINVAL;
break;
@@ -1080,7 +1085,7 @@
n = NULL;
nat_stats.ns_rules++;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
pfil_delayed_copy = 0;
#endif
if (getlock) {
@@ -1168,9 +1173,10 @@
if (n->in_use == 0) {
if (n->in_apr)
appr_free(n->in_apr);
+ MUTEX_DESTROY(&n->in_lock);
KFREE(n);
nat_stats.ns_rules--;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
#endif
@@ -1660,11 +1666,12 @@
/* Delete a nat entry from the various lists and table. If NAT logging is */
/* enabled then generate a NAT log record for this event. */
/* ------------------------------------------------------------------------ */
-static void nat_delete(nat, logtype)
+void nat_delete(nat, logtype)
struct nat *nat;
int logtype;
{
struct ipnat *ipn;
+ int removed = 0;
if (logtype != 0 && nat_logging != 0)
nat_log(nat, logtype);
@@ -1674,6 +1681,8 @@
* nat_pnext is set.
*/
if (nat->nat_pnext != NULL) {
+ removed = 1;
+
nat_stats.ns_bucketlen[0][nat->nat_hv[0]]--;
nat_stats.ns_bucketlen[1][nat->nat_hv[1]]--;
@@ -1714,9 +1723,24 @@
nat_stats.ns_expire++;
MUTEX_ENTER(&nat->nat_lock);
- if (nat->nat_ref > 1) {
+ /*
+ * NL_DESTROY should only be passed in when we've got nat_ref >= 2.
+ * This happens when a nat'd packet is blocked and we want to throw
+ * away the NAT session.
+ */
+ if (logtype == NL_DESTROY) {
+ if (nat->nat_ref > 2) {
+ nat->nat_ref -= 2;
+ MUTEX_EXIT(&nat->nat_lock);
+ if (removed)
+ nat_stats.ns_orphans++;
+ return;
+ }
+ } else if (nat->nat_ref > 1) {
nat->nat_ref--;
MUTEX_EXIT(&nat->nat_lock);
+ if (removed)
+ nat_stats.ns_orphans++;
return;
}
MUTEX_EXIT(&nat->nat_lock);
@@ -1725,6 +1749,8 @@
* At this point, nat_ref is 1, doing "--" would make it 0..
*/
nat->nat_ref = 0;
+ if (!removed)
+ nat_stats.ns_orphans--;
#ifdef IPFILTER_SYNC
if (nat->nat_sync)
@@ -1824,6 +1850,7 @@
if (n->in_use == 0) {
if (n->in_apr != NULL)
appr_free(n->in_apr);
+ MUTEX_DESTROY(&n->in_lock);
KFREE(n);
nat_stats.ns_rules--;
} else {
@@ -1832,7 +1859,7 @@
}
i++;
}
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
pfil_delayed_copy = 1;
#endif
nat_masks = 0;
@@ -2498,10 +2525,12 @@
}
if (nat_finalise(fin, nat, &ni, tcp, natsave, direction) == -1) {
+ fr_nat_doflush = 1;
goto badnat;
}
if (flags & SI_WILDP)
nat_stats.ns_wilds++;
+ fin->fin_flx |= FI_NEWNAT;
goto done;
badnat:
nat_stats.ns_badnat++;
@@ -3011,10 +3040,22 @@
}
if (sumd2 != 0) {
+ ipnat_t *np;
+
+ np = nat->nat_ptr;
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16);
- fix_incksum(fin, &icmp->icmp_cksum, sumd2);
+
+ if ((odst == 0) && (dir == NAT_OUTBOUND) &&
+ (fin->fin_rev == 0) && (np != NULL) &&
+ (np->in_redir & NAT_REDIRECT)) {
+ fix_outcksum(fin, &icmp->icmp_cksum,
+ sumd2);
+ } else {
+ fix_incksum(fin, &icmp->icmp_cksum,
+ sumd2);
+ }
}
}
} else if (((flags & IPN_ICMPQUERY) != 0) && (dlen >= 8)) {
@@ -4684,9 +4725,10 @@
if (in->in_use == 0 && (in->in_flags & IPN_DELETE)) {
if (in->in_apr)
appr_free(in->in_apr);
+ MUTEX_DESTROY(&in->in_lock);
KFREE(in);
nat_stats.ns_rules--;
-#if SOLARIS
+#if SOLARIS && !defined(_INET_IP_STACK_H)
if (nat_stats.ns_rules == 0)
pfil_delayed_copy = 1;
#endif
@@ -5013,10 +5055,11 @@
ipnat_t *ipn, *nextipnat = NULL, zeroipn;
nat_t *nat, *nextnat = NULL, zeronat;
int error = 0, count;
- ipftoken_t *freet;
char *dst;
- freet = NULL;
+ count = itp->igi_nitems;
+ if (count < 1)
+ return ENOSPC;
READ_ENTER(&ipf_nat);
@@ -5054,61 +5097,52 @@
}
dst = itp->igi_data;
- for (count = itp->igi_nitems; count > 0; count--) {
+ for (;;) {
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
if (nexthm != NULL) {
- if (nexthm->hm_next == NULL) {
- freet = t;
- count = 1;
- hm = NULL;
- }
if (count == 1) {
ATOMIC_INC32(nexthm->hm_ref);
+ t->ipt_data = nexthm;
}
} else {
bzero(&zerohm, sizeof(zerohm));
nexthm = &zerohm;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_IPNAT :
if (nextipnat != NULL) {
- if (nextipnat->in_next == NULL) {
- freet = t;
- count = 1;
- ipn = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextipnat->in_lock);
nextipnat->in_use++;
MUTEX_EXIT(&nextipnat->in_lock);
+ t->ipt_data = nextipnat;
}
} else {
bzero(&zeroipn, sizeof(zeroipn));
nextipnat = &zeroipn;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_NAT :
if (nextnat != NULL) {
- if (nextnat->nat_next == NULL) {
- count = 1;
- freet = t;
- nat = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextnat->nat_lock);
nextnat->nat_ref++;
MUTEX_EXIT(&nextnat->nat_lock);
+ t->ipt_data = nextnat;
}
} else {
bzero(&zeronat, sizeof(zeronat));
nextnat = &zeronat;
count = 1;
+ t->ipt_data = NULL;
}
break;
default :
@@ -5116,20 +5150,12 @@
}
RWLOCK_EXIT(&ipf_nat);
- if (freet != NULL) {
- ipf_freetoken(freet);
- freet = NULL;
- }
-
+ /*
+ * Copying out to user space needs to be done without the lock.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- if (hm != NULL) {
- WRITE_ENTER(&ipf_nat);
- fr_hostmapdel(&hm);
- RWLOCK_EXIT(&ipf_nat);
- }
- t->ipt_data = nexthm;
error = COPYOUT(nexthm, dst, sizeof(*nexthm));
if (error != 0)
error = EFAULT;
@@ -5138,9 +5164,6 @@
break;
case IPFGENITER_IPNAT :
- if (ipn != NULL)
- fr_ipnatderef(&ipn);
- t->ipt_data = nextipnat;
error = COPYOUT(nextipnat, dst, sizeof(*nextipnat));
if (error != 0)
error = EFAULT;
@@ -5149,9 +5172,6 @@
break;
case IPFGENITER_NAT :
- if (nat != NULL)
- fr_natderef(&nat);
- t->ipt_data = nextnat;
error = COPYOUT(nextnat, dst, sizeof(*nextnat));
if (error != 0)
error = EFAULT;
@@ -5163,29 +5183,52 @@
if ((count == 1) || (error != 0))
break;
+ count--;
+
READ_ENTER(&ipf_nat);
+ /*
+ * We need to have the lock again here to make sure that
+ * using _next is consistent.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- hm = nexthm;
- nexthm = hm->hm_next;
+ nexthm = nexthm->hm_next;
break;
-
case IPFGENITER_IPNAT :
- ipn = nextipnat;
- nextipnat = ipn->in_next;
+ nextipnat = nextipnat->in_next;
break;
-
case IPFGENITER_NAT :
- nat = nextnat;
- nextnat = nat->nat_next;
- break;
- default :
+ nextnat = nextnat->nat_next;
break;
}
}
+
+ switch (itp->igi_type)
+ {
+ case IPFGENITER_HOSTMAP :
+ if (hm != NULL) {
+ WRITE_ENTER(&ipf_nat);
+ fr_hostmapdel(&hm);
+ RWLOCK_EXIT(&ipf_nat);
+ }
+ break;
+ case IPFGENITER_IPNAT :
+ if (ipn != NULL) {
+ fr_ipnatderef(&ipn);
+ }
+ break;
+ case IPFGENITER_NAT :
+ if (nat != NULL) {
+ fr_natderef(&nat);
+ }
+ break;
+ default :
+ break;
+ }
+
return error;
}
@@ -5394,3 +5437,44 @@
nat_delete(entry, NL_FLUSH);
return 0;
}
+
+
+/* ------------------------------------------------------------------------ */
+/* Function: nat_gettable */
+/* Returns: int - 0 = success, else error */
+/* Parameters: data(I) - pointer to ioctl data */
+/* */
+/* This function handles ioctl requests for tables of nat information. */
+/* At present the only table it deals with is the hash bucket statistics. */
+/* ------------------------------------------------------------------------ */
+static int nat_gettable(data)
+char *data;
+{
+ ipftable_t table;
+ int error;
+
+ error = fr_inobj(data, &table, IPFOBJ_GTABLE);
+ if (error != 0)
+ return error;
+
+ switch (table.ita_type)
+ {
+ case IPFTABLE_BUCKETS_NATIN :
+ error = COPYOUT(nat_stats.ns_bucketlen[0], table.ita_table,
+ ipf_nattable_sz * sizeof(u_long));
+ break;
+
+ case IPFTABLE_BUCKETS_NATOUT :
+ error = COPYOUT(nat_stats.ns_bucketlen[1], table.ita_table,
+ ipf_nattable_sz * sizeof(u_long));
+ break;
+
+ default :
+ return EINVAL;
+ }
+
+ if (error != 0) {
+ error = EFAULT;
+ }
+ return error;
+}
Index: ip_nat.h
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_nat.h,v
retrieving revision 1.12
diff -u -r1.12 ip_nat.h
--- ip_nat.h 14 Sep 2007 11:28:46 -0000 1.12
+++ ip_nat.h 30 Sep 2007 07:10:19 -0000
@@ -6,7 +6,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
- * Id: ip_nat.h,v 2.90.2.17 2007/05/11 10:19:11 darrenr Exp
+ * $Id: ip_nat.h,v 2.90.2.20 2007/09/25 08:27:32 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@@ -363,6 +363,7 @@
hostmap_t *ns_maplist;
u_long *ns_bucketlen[2];
u_long ns_ticks;
+ u_int ns_orphans;
} natstat_t;
typedef struct natlog {
@@ -384,6 +385,7 @@
#define NL_NEWRDR NAT_REDIRECT
#define NL_NEWBIMAP NAT_BIMAP
#define NL_NEWBLOCK NAT_MAPBLK
+#define NL_DESTROY 0xfffc
#define NL_CLONE 0xfffd
#define NL_FLUSH 0xfffe
#define NL_EXPIRE 0xffff
@@ -447,6 +449,7 @@
extern nat_t *nat_lookupredir __P((natlookup_t *));
extern nat_t *nat_icmperrorlookup __P((fr_info_t *, int));
extern nat_t *nat_icmperror __P((fr_info_t *, u_int *, int));
+extern void nat_delete __P((struct nat *, int));
extern int nat_insert __P((nat_t *, int));
extern int fr_checknatout __P((fr_info_t *, u_32_t *));
Index: ip_state.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_state.c,v
retrieving revision 1.29
diff -u -r1.29 ip_state.c
--- ip_state.c 17 Sep 2007 06:56:15 -0000 1.29
+++ ip_state.c 30 Sep 2007 07:10:21 -0000
@@ -117,7 +117,7 @@
__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.29 2007/09/17 06:56:15 martti Exp $");
#else
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)Id: ip_state.c,v 2.186.2.69 2007/05/26 13:05:14 darrenr Exp";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.78 2007/09/20 12:51:53 darrenr Exp $";
#endif
#endif
@@ -657,8 +657,8 @@
int error;
error = fr_inobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
+ if (error != 0)
+ return error;
isn = ips.ips_next;
if (isn == NULL) {
@@ -687,9 +687,7 @@
bcopy((char *)isn->is_rule, (char *)&ips.ips_fr,
sizeof(ips.ips_fr));
error = fr_outobj(data, &ips, IPFOBJ_STATESAVE);
- if (error)
- return EFAULT;
- return 0;
+ return error;
}
@@ -1444,7 +1442,7 @@
is->is_state[!source] = IPF_TCPS_CLOSED;
fr_movequeue(&is->is_sti, is->is_sti.tqe_ifq,
&ips_deletetq);
- MUTEX_ENTER(&is->is_lock);
+ MUTEX_EXIT(&is->is_lock);
return 0;
}
}
@@ -2308,8 +2306,6 @@
ipstate_t **isp;
u_int hvm;
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
hvm = is->is_hv;
/*
* Remove the hash from the old location...
@@ -2897,8 +2893,6 @@
int why;
{
- ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0);
-
/*
* Since we want to delete this, remove it from the state table,
* where it can be found & used, first.
@@ -4072,7 +4066,7 @@
if (itp->igi_data == NULL)
return EFAULT;
- if (itp->igi_nitems == 0)
+ if (itp->igi_nitems < 1)
return ENOSPC;
if (itp->igi_type != IPFGENITER_STATE)
@@ -4094,33 +4088,29 @@
next = is->is_next;
}
- for (count = itp->igi_nitems; count > 0; count--) {
+ count = itp->igi_nitems;
+ for (;;) {
if (next != NULL) {
/*
* If we find a state entry to use, bump its
* reference count so that it can be used for
* is_next when we come back.
*/
- MUTEX_ENTER(&next->is_lock);
- next->is_ref++;
- MUTEX_EXIT(&next->is_lock);
- token->ipt_data = next;
+ if (count == 1) {
+ MUTEX_ENTER(&next->is_lock);
+ next->is_ref++;
+ MUTEX_EXIT(&next->is_lock);
+ token->ipt_data = next;
+ }
} else {
bzero(&zero, sizeof(zero));
next = &zero;
- token->ipt_data = (void *)-1;
count = 1;
+ token->ipt_data = NULL;
}
RWLOCK_EXIT(&ipf_state);
/*
- * If we had a prior pointer to a state entry, release it.
- */
- if (is != NULL) {
- fr_statederef(&is);
- }
-
- /*
* This should arguably be via fr_outobj() so that the state
* structure can (if required) be massaged going out.
*/
@@ -4131,9 +4121,14 @@
break;
dst += sizeof(*next);
+ count--;
+
READ_ENTER(&ipf_state);
- is = next;
- next = is->is_next;
+ next = next->is_next;
+ }
+
+ if (is != NULL) {
+ fr_statederef(&is);
}
return error;
From: Martti Kuparinen <martti.kuparinen@iki.fi>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@NetBSD.org, gnats-admin@NetBSD.org,
netbsd-bugs@NetBSD.org, stix@stix.id.au
Subject: Re: kern/37037
Date: Sun, 30 Sep 2007 19:01:07 +0300
> Could you please try this patch (also at http://users.piuha.net/martti/tmp/p)
After compiling the kernel make sure you also build and install the
userland:
cd /usr/src/sys
make includes
cd /usr/src/usr.sbin/ipf
make clean
make
make install
From: Paul Ripke <stix@stix.id.au>
To: Martti Kuparinen <martti.kuparinen@iki.fi>
Cc: Juan RP <juan@xtrarom.org>,
Michael van Elst <mlelstv@serpens.de>, pavel@netbsd.org,
Darren Reed <darrenr@netbsd.org>,
NetBSD gnats-bugs <gnats-bugs@NetBSD.org>
Subject: Re: kern/37037
Date: Mon, 1 Oct 2007 22:30:07 +1000
On Mon, Oct 01, 2007 at 08:43:43AM +0300, Martti Kuparinen wrote:
> >Does this patch break userland compatibility? if that's the case, please
> >fix it correctly.
>
> Try the new patch: http://users.piuha.net/martti/tmp/nat2.diff
>
> Changes: I did not add "fin_cksum" to the fr_info_t structure...
Tested - I needed to install a new ipnat(8) (expected?), otherwise:
# ipnat -l
ioctl(SIOCGNATS): Invalid argument
No longer get "Data modified on freelist", but I'm still waiting for
any of the RDR sessions to age out. I'll check again in the morning.
--
Paul Ripke
From: Paul Ripke <stix@stix.id.au>
To: NetBSD gnats-bugs <gnats-bugs@NetBSD.org>
Cc:
Subject: Re: kern/37037
Date: Wed, 3 Oct 2007 09:16:55 +1000
For the benefit of the PR:
----- Forwarded message from Michael van Elst <mlelstv@serpens.de> -----
On Tue, Oct 02, 2007 at 08:32:19AM +1000, Paul Ripke wrote:
> FYI: the RDR sessions definitely are not expiring. Does this issue
> deserve another send-pr?
> The verbose state appears like:
>
> RDR 127.0.0.1 3128 <- -> 209.85.197.147 80 [192.168.254.5 1418]
> ttl 863347 use 0 sumd 0xf3ff/0xf3ff pr 6 bkt 849/267 flags 1
> ifp X,X bytes 1495/639 pkts 6/5 ipsumd e817
> RDR 127.0.0.1 3128 <- -> 63.245.209.21 80 [192.168.254.5 4654]
> ttl 785177 use 0 sumd 0x79de/0x79de pr 6 bkt 1874/996 flags 1
> ifp X,X bytes 891/900 pkts 6/5 ipsumd 6df6
According to the TTL the session expires after 5 days (two ticks per
second). Apparently the filter doesn't handle the end of the
TCP session.
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
----- End forwarded message -----
--
Paul Ripke
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: stix@stix.id.au, Michael van Elst <mlelstv@serpens.de>
Subject: Re: kern/37037: ipnat: Data modified on freelist
Date: Wed, 3 Oct 2007 12:03:11 +0200
--5vNYLRcllDrimb99
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Could you try if this patch alone fixes the write after free problem
for you too? Restore the original RC2 userland binaries/headers and just
try a kernel build with this patch (against RC2, without Martti's patch).
It won't touch the tcp rdr timeouts, but that should be a different PR
(and IMHO is not fixed in IPF 4.1.27, but maybe I overlooked something).
Martin
--5vNYLRcllDrimb99
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch
Index: ip_nat.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_nat.c,v
retrieving revision 1.19.2.7
diff -c -u -p -r1.19.2.7 ip_nat.c
--- ip_nat.c 16 Sep 2007 15:46:48 -0000 1.19.2.7
+++ ip_nat.c 3 Oct 2007 09:57:44 -0000
@@ -5013,10 +5013,11 @@ ipfgeniter_t *itp;
ipnat_t *ipn, *nextipnat = NULL, zeroipn;
nat_t *nat, *nextnat = NULL, zeronat;
int error = 0, count;
- ipftoken_t *freet;
char *dst;
- freet = NULL;
+ count = itp->igi_nitems;
+ if (count < 1)
+ return ENOSPC;
READ_ENTER(&ipf_nat);
@@ -5054,61 +5055,52 @@ ipfgeniter_t *itp;
}
dst = itp->igi_data;
- for (count = itp->igi_nitems; count > 0; count--) {
+ for (;;) {
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
if (nexthm != NULL) {
- if (nexthm->hm_next == NULL) {
- freet = t;
- count = 1;
- hm = NULL;
- }
if (count == 1) {
ATOMIC_INC32(nexthm->hm_ref);
+ t->ipt_data = nexthm;
}
} else {
bzero(&zerohm, sizeof(zerohm));
nexthm = &zerohm;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_IPNAT :
if (nextipnat != NULL) {
- if (nextipnat->in_next == NULL) {
- freet = t;
- count = 1;
- ipn = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextipnat->in_lock);
nextipnat->in_use++;
MUTEX_EXIT(&nextipnat->in_lock);
+ t->ipt_data = nextipnat;
}
} else {
bzero(&zeroipn, sizeof(zeroipn));
nextipnat = &zeroipn;
count = 1;
+ t->ipt_data = NULL;
}
break;
case IPFGENITER_NAT :
if (nextnat != NULL) {
- if (nextnat->nat_next == NULL) {
- count = 1;
- freet = t;
- nat = NULL;
- }
if (count == 1) {
MUTEX_ENTER(&nextnat->nat_lock);
nextnat->nat_ref++;
MUTEX_EXIT(&nextnat->nat_lock);
+ t->ipt_data = nextnat;
}
} else {
bzero(&zeronat, sizeof(zeronat));
nextnat = &zeronat;
count = 1;
+ t->ipt_data = NULL;
}
break;
default :
@@ -5116,20 +5108,12 @@ ipfgeniter_t *itp;
}
RWLOCK_EXIT(&ipf_nat);
- if (freet != NULL) {
- ipf_freetoken(freet);
- freet = NULL;
- }
-
+ /*
+ * Copying out to user space needs to be done without the lock.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- if (hm != NULL) {
- WRITE_ENTER(&ipf_nat);
- fr_hostmapdel(&hm);
- RWLOCK_EXIT(&ipf_nat);
- }
- t->ipt_data = nexthm;
error = COPYOUT(nexthm, dst, sizeof(*nexthm));
if (error != 0)
error = EFAULT;
@@ -5138,9 +5122,6 @@ ipfgeniter_t *itp;
break;
case IPFGENITER_IPNAT :
- if (ipn != NULL)
- fr_ipnatderef(&ipn);
- t->ipt_data = nextipnat;
error = COPYOUT(nextipnat, dst, sizeof(*nextipnat));
if (error != 0)
error = EFAULT;
@@ -5149,9 +5130,6 @@ ipfgeniter_t *itp;
break;
case IPFGENITER_NAT :
- if (nat != NULL)
- fr_natderef(&nat);
- t->ipt_data = nextnat;
error = COPYOUT(nextnat, dst, sizeof(*nextnat));
if (error != 0)
error = EFAULT;
@@ -5163,29 +5141,52 @@ ipfgeniter_t *itp;
if ((count == 1) || (error != 0))
break;
+ count--;
+
READ_ENTER(&ipf_nat);
+ /*
+ * We need to have the lock again here to make sure that
+ * using _next is consistent.
+ */
switch (itp->igi_type)
{
case IPFGENITER_HOSTMAP :
- hm = nexthm;
- nexthm = hm->hm_next;
+ nexthm = nexthm->hm_next;
break;
-
case IPFGENITER_IPNAT :
- ipn = nextipnat;
- nextipnat = ipn->in_next;
+ nextipnat = nextipnat->in_next;
break;
-
case IPFGENITER_NAT :
- nat = nextnat;
- nextnat = nat->nat_next;
- break;
- default :
+ nextnat = nextnat->nat_next;
break;
}
}
+
+ switch (itp->igi_type)
+ {
+ case IPFGENITER_HOSTMAP :
+ if (hm != NULL) {
+ WRITE_ENTER(&ipf_nat);
+ fr_hostmapdel(&hm);
+ RWLOCK_EXIT(&ipf_nat);
+ }
+ break;
+ case IPFGENITER_IPNAT :
+ if (ipn != NULL) {
+ fr_ipnatderef(&ipn);
+ }
+ break;
+ case IPFGENITER_NAT :
+ if (nat != NULL) {
+ fr_natderef(&nat);
+ }
+ break;
+ default :
+ break;
+ }
+
return error;
}
--5vNYLRcllDrimb99--
From: Paul Ripke <stix@stix.id.au>
To: Martin Husemann <martin@duskware.de>
Cc: gnats-bugs@NetBSD.org, Michael van Elst <mlelstv@serpens.de>
Subject: Re: kern/37037: ipnat: Data modified on freelist
Date: Thu, 4 Oct 2007 00:40:29 +1000
That patch appears to fix the write after free issue fine. Thanks!
Should I raise another pr for the RDR TTL issue?
--
Paul Ripke
From: Juan Romero Pardines <xtraeme@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: PR/37037 CVS commit: [netbsd-4] src/sys/dist/ipf/netinet
Date: Fri, 12 Oct 2007 16:50:39 +0000 (UTC)
Module Name: src
Committed By: xtraeme
Date: Fri Oct 12 16:50:38 UTC 2007
Modified Files:
src/sys/dist/ipf/netinet [netbsd-4]: ip_nat.c
Log Message:
Pullup following revision(s) (requested by martin in ticket #916):
sys/dist/ipf/netinet/ip_nat.c: patch
Fix PR kern/37037 "ipnat: Data modified on freelist", verified by
the submitter.
To generate a diff of this commit:
cvs rdiff -r1.19.2.7 -r1.19.2.8 src/sys/dist/ipf/netinet/ip_nat.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: xtraeme@netbsd.org
State-Changed-When: Sun, 14 Oct 2007 00:51:15 +0000
State-Changed-Why:
Fix was applied yesterday, thanks.
From: Pavel Cahyna <pavel@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: PR/37037 CVS commit: [netbsd-4] src/sys/dist/ipf/netinet
Date: Sat, 27 Oct 2007 15:58:57 +0000 (UTC)
Module Name: src
Committed By: pavel
Date: Sat Oct 27 15:58:57 UTC 2007
Modified Files:
src/sys/dist/ipf/netinet [netbsd-4]: ip_nat.c ip_nat.h ip_state.c
ip_state.h
Log Message:
revert pullup #880. It reportedly causes RDR sessions to not expire and
fill up the NAT table. See PR kern/37037 and possibly kern/37174.
To generate a diff of this commit:
cvs rdiff -r1.19.2.8 -r1.19.2.9 src/sys/dist/ipf/netinet/ip_nat.c
cvs rdiff -r1.7.12.4 -r1.7.12.5 src/sys/dist/ipf/netinet/ip_nat.h
cvs rdiff -r1.15.2.8 -r1.15.2.9 src/sys/dist/ipf/netinet/ip_state.c
cvs rdiff -r1.5.12.4 -r1.5.12.5 src/sys/dist/ipf/netinet/ip_state.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Paul Ripke <stix@stix.id.au>
To: gnats-bugs@NetBSD.org
Cc: Darren Reed <darrenr@netbsd.org>,
Martti Kuparinen <martti.kuparinen@iki.fi>,
Juan RP <juan@xtrarom.org>, Michael van Elst <mlelstv@serpens.de>,
Pavel Cahyna <pavel@netbsd.org>
Subject: Re: PR/37037 CVS commit: [netbsd-4] src/sys/dist/ipf/netinet
Date: Tue, 13 Nov 2007 12:28:37 +1100
Confirmed (belatedly) it works fine in my environment. RDR sessions
expire as they should, and I haven't seen any occurrences of
"Data modified on freelist".
--
Paul Ripke
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.