summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorcsjp <csjp@FreeBSD.org>2006-01-20 05:35:27 +0000
committercsjp <csjp@FreeBSD.org>2006-01-20 05:35:27 +0000
commit789674670e39102ca2d71ce85d9f93840ab2e564 (patch)
treef7e6bc762621502a8be7ab4d574676b3e26f0411 /sys
parent5f9b2961c344fae5d18e1938377ac1cd2fef24a5 (diff)
downloadFreeBSD-src-789674670e39102ca2d71ce85d9f93840ab2e564.zip
FreeBSD-src-789674670e39102ca2d71ce85d9f93840ab2e564.tar.gz
- Change the return type for init_tables from void to int so we can propagate
errors from rn_inithead back to the ipfw initialization function. - Check return value of rn_inithead for failure, if table allocation has failed for any reason, free up any tables we have created and return ENOMEM - In ipfw_init check the return value of init_tables and free up any mutexes or UMA zones which may have been created. - Assert that the supplied table is not NULL before attempting to dereference. This fixes panics which were a result of invalid memory accesses due to failed table allocation. This is an issue mainly because the R_Zalloc function is a malloc(M_NOWAIT) wrapper, thus making it possible for allocations to fail. Found by: Coverity Prevent (tm) Coverity ID: CID79 MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip_fw2.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index ffc4993..79e0e2b 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -1695,15 +1695,6 @@ lookup_next_rule(struct ip_fw *me)
return rule;
}
-static void
-init_tables(struct ip_fw_chain *ch)
-{
- int i;
-
- for (i = 0; i < IPFW_TABLES_MAX; i++)
- rn_inithead((void **)&ch->tables[i], 32);
-}
-
static int
add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
uint8_t mlen, uint32_t value)
@@ -1780,6 +1771,7 @@ flush_table(struct ip_fw_chain *ch, uint16_t tbl)
if (tbl >= IPFW_TABLES_MAX)
return (EINVAL);
rnh = ch->tables[tbl];
+ KASSERT(rnh != NULL, ("NULL IPFW table"));
rnh->rnh_walktree(rnh, flush_table_entry, rnh);
return (0);
}
@@ -1796,6 +1788,23 @@ flush_tables(struct ip_fw_chain *ch)
}
static int
+init_tables(struct ip_fw_chain *ch)
+{
+ int i;
+ uint16_t j;
+
+ for (i = 0; i < IPFW_TABLES_MAX; i++) {
+ if (!rn_inithead((void **)&ch->tables[i], 32)) {
+ for (j = 0; j < i; j++) {
+ (void) flush_table(ch, j);
+ }
+ return (ENOMEM);
+ }
+ }
+ return (0);
+}
+
+static int
lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
uint32_t *val)
{
@@ -4204,7 +4213,13 @@ ipfw_init(void)
printf("limited to %d packets/entry by default\n",
verbose_limit);
- init_tables(&layer3_chain);
+ error = init_tables(&layer3_chain);
+ if (error) {
+ IPFW_DYN_LOCK_DESTROY();
+ IPFW_LOCK_DESTROY(&layer3_chain);
+ uma_zdestroy(ipfw_dyn_rule_zone);
+ return (error);
+ }
ip_fw_ctl_ptr = ipfw_ctl;
ip_fw_chk_ptr = ipfw_chk;
callout_reset(&ipfw_timeout, hz, ipfw_tick, NULL);
OpenPOWER on IntegriCloud