Mercurial > illumos > illumos-gate
changeset 4380:f81c6be79aba
6528018 For SIOCSTPUT, can grab ipf_nat lock even if specified not to.
6528419 IPfilter with nat can leak memory
6528552 IPfilter SIOCSTPUT doesn't initialize filter rule state properly
6532393 IPfilter NAT rules with bad proxy labels will get loaded anyway.
author | jojemann |
---|---|
date | Mon, 04 Jun 2007 08:30:15 -0700 |
parents | 97a7ff056a78 |
children | 2690f52859a1 |
files | usr/src/uts/common/inet/ipf/ip_nat.c |
diffstat | 1 files changed, 32 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ipf/ip_nat.c Mon Jun 04 07:35:45 2007 -0700 +++ b/usr/src/uts/common/inet/ipf/ip_nat.c Mon Jun 04 08:30:15 2007 -0700 @@ -7,7 +7,7 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +#pragma ident "%Z%%M% %I% %E% SMI"$ #if defined(KERNEL) || defined(_KERNEL) # undef KERNEL @@ -167,7 +167,7 @@ static INLINE int nat_icmperrortype4 __P((int)); static INLINE int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, tcphdr_t *, nat_t **, int)); -static INLINE void nat_resolverule __P((ipnat_t *, ipf_stack_t *)); +static INLINE int nat_resolverule __P((ipnat_t *, ipf_stack_t *)); static nat_t *fr_natclone __P((fr_info_t *, nat_t *)); static void nat_mssclamp __P((tcphdr_t *, u_32_t, u_short *)); static INLINE int nat_wildok __P((nat_t *, int, int, int, int)); @@ -889,11 +889,8 @@ { int error = 0, i, j; - nat_resolverule(n, ifs); - if (n->in_plabel[0] != '\0') { - if (n->in_apr == NULL) - return ENOENT; - } + if (nat_resolverule(n, ifs) != 0) + return ENOENT; if ((n->in_age[0] == 0) && (n->in_age[1] != 0)) return EINVAL; @@ -1010,14 +1007,16 @@ /* ------------------------------------------------------------------------ */ /* Function: nat_resolvrule */ -/* Returns: Nil */ +/* Returns: int - 0 == success, -1 == failure */ /* Parameters: n(I) - pointer to NAT rule */ /* */ -/* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */ -/* from information passed to the kernel, then add it to the appropriate */ -/* NAT rule table(s). */ +/* Resolve some of the details inside the NAT rule. Includes resolving */ +/* any specified interfaces and proxy labels, and determines whether or not */ +/* all proxy labels are correctly specified. */ +/* */ +/* Called by nat_siocaddnat() (SIOCADNAT) and fr_natputent (SIOCSTPUT). */ /* ------------------------------------------------------------------------ */ -static void nat_resolverule(n, ifs) +static int nat_resolverule(n, ifs) ipnat_t *n; ipf_stack_t *ifs; { @@ -1034,7 +1033,10 @@ if (n->in_plabel[0] != '\0') { n->in_apr = appr_lookup(n->in_p, n->in_plabel, ifs); + if (n->in_apr == NULL) + return -1; } + return 0; } @@ -1362,7 +1364,10 @@ ATOMIC_INC(ifs->ifs_nat_stats.ns_rules); - nat_resolverule(in, ifs); + if (nat_resolverule(in, ifs) != 0) { + error = ESRCH; + goto junkput; + } } /* @@ -1456,13 +1461,20 @@ goto junkput; } ipnn->ipn_nat.nat_fr = fr; - fr->fr_ref = 1; (void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE); bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr)); + + fr->fr_ref = 1; + fr->fr_dsize = 0; + fr->fr_data = NULL; + fr->fr_type = FR_T_NONE; + MUTEX_NUKE(&fr->fr_lock); MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock"); } else { - READ_ENTER(&ifs->ifs_ipf_nat); + if (getlock) { + READ_ENTER(&ifs->ifs_ipf_nat); + } for (n = ifs->ifs_nat_instances; n; n = n->nat_next) if (n->nat_fr == fr) break; @@ -1472,8 +1484,9 @@ fr->fr_ref++; MUTEX_EXIT(&fr->fr_lock); } - RWLOCK_EXIT(&ifs->ifs_ipf_nat); - + if (getlock) { + RWLOCK_EXIT(&ifs->ifs_ipf_nat); + } if (!n) { error = ESRCH; goto junkput; @@ -2241,6 +2254,7 @@ natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p, fin->fin_src, fin->fin_dst); if (natl != NULL) { + KFREE(nat); nat = natl; goto done; } @@ -2258,6 +2272,7 @@ natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p, fin->fin_src, fin->fin_dst); if (natl != NULL) { + KFREE(nat); nat = natl; goto done; }