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>