Date: Fri, 11 Oct 2002 00:02:16 -0700 From: Terry Lambert <tlambert2@mindspring.com> To: abe <abe@informationwave.net> Cc: Bill Fumerola <billf@mu.org>, hackers@freebsd.org Subject: Re: fatal trap 12 kernel panic Message-ID: <3DA67778.3312A104@mindspring.com> References: <20021011044636.GA84506@dipole.informationwave.net> <20021011045013.GO80284@elvis.mu.org> <20021011044956.GA87029@dipole.informationwave.net>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------F3BB264D75970FAB27878B65
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
abe wrote:
> On Thu, Oct 10, 2002 at 09:50:13PM -0700, Bill Fumerola wrote:
> > On Fri, Oct 11, 2002 at 12:46:36AM -0400, abe wrote:
> > static u_int32_t dyn_buckets = 256; /* must be power of 2 */
>
> Well another issue solved, need thicker glasses it appears. Thanks much
> Bill. Funny thing is, it's been running without issue for almost a year
> now. Interesting.
Try setting it back to 500, and see if you can get a crash.
The value of dyn_buckets is seperate from the curr_dyn_buckets
in both netinet/ipfw.c and netinet/ipfw2.c.
In theory, the value is checked for a power of 2 value before
it is used, and that's used to resize. If it isn't a power of
2, then it gets reset to back to curr_dyn_buckets.
There is a window in the resize in netinet/ipfw2.c that could
cause a probem (the old array is freed before the new array
has been successfully allocated -- order of operation bug, IMO).
But there should not be an issue with the size being changed...
particularly on ip_output() called from send() called from user
space.
There's also a problem with initial sizing, and a problem if the
initial allocation fails, and a couple other problems. I have
attached a patch which fixes these problems.
Note: This patch may not fix your "500" problem... the correct
way to fix that is probably to have the sysctl for dyn_buckets
use a set procedure, which refuses the set if it's not a power
of 2 and/or rounds it up to the next power of 2 < 65536.
-- Terry
--------------F3BB264D75970FAB27878B65
Content-Type: text/plain; charset=us-ascii;
name="ipfw.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="ipfw.diff"
Index: ip_fw.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_fw.c,v
retrieving revision 1.188
diff -u -r1.188 ip_fw.c
--- ip_fw.c 22 Jun 2002 11:51:02 -0000 1.188
+++ ip_fw.c 11 Oct 2002 03:01:38 -0000
@@ -862,23 +862,40 @@
struct ipfw_dyn_rule *r ;
int i ;
+
+ /* new allocation or reallocation */
if (ipfw_dyn_v == NULL ||
(dyn_count == 0 && dyn_buckets != curr_dyn_buckets)) {
- /* try reallocation, make sure we have a power of 2 */
+ /* make sure we have a power of 2 */
u_int32_t i = dyn_buckets ;
while ( i > 0 && (i & 1) == 0 )
i >>= 1 ;
if (i != 1) /* not a power of 2 */
dyn_buckets = curr_dyn_buckets ; /* reset */
- else {
- curr_dyn_buckets = dyn_buckets ;
- if (ipfw_dyn_v != NULL)
- free(ipfw_dyn_v, M_IPFW);
- ipfw_dyn_v = malloc(curr_dyn_buckets * sizeof r,
+
+ /* new allocation or reallocation; avoid the realloction on reset */
+ if (ipfw_dyn_v == NULL ||
+ (dyn_count == 0 && dyn_buckets != curr_dyn_buckets)) {
+ ipfw_dyn_rule **new_ipfw_dyn_v;
+
+ /*
+ * try the allocation; if it's a reallocation, and the malloc
+ * fails, keep the old area and reset, instead.
+ */
+ new_ipfw_dyn_v = malloc(dyn_buckets * sizeof r,
M_IPFW, M_DONTWAIT | M_ZERO);
- if (ipfw_dyn_v == NULL)
- return NULL; /* failed ! */
+ if (new_ipfw_dyn_v != NULL) {
+ if (ipfw_dyn_v != NULL)
+ free(ipfw_dyn_v, M_IPFW);
+ ipfw_dyn_v = new_ipfw_dyn_v;
+ curr_dyn_buckets = dyn_buckets ;
+ } else {
+ dyn_buckets = curr_dyn_buckets ; /* reset */
+ }
}
+
+ if (ipfw_dyn_v == NULL)
+ return NULL; /* failed ! */
}
i = hash_packet(id);
--------------F3BB264D75970FAB27878B65--
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3DA67778.3312A104>
