summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ipfilter/netinet
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>2008-07-24 12:35:05 +0000
committerdarrenr <darrenr@FreeBSD.org>2008-07-24 12:35:05 +0000
commit49ad2adb91673def2dfa0f293612e2de5e3a29af (patch)
treefbe3003abde766264fafdbbd7e484eafc5be4ad5 /sys/contrib/ipfilter/netinet
parent308672b0059651d854c35e673c94d0f76d84c25f (diff)
downloadFreeBSD-src-49ad2adb91673def2dfa0f293612e2de5e3a29af.zip
FreeBSD-src-49ad2adb91673def2dfa0f293612e2de5e3a29af.tar.gz
2020447 IPFilter's NAT can undo name server random port selection
Approved by: darrenr MFC after: 1 week Security: CERT VU#521769
Diffstat (limited to 'sys/contrib/ipfilter/netinet')
-rw-r--r--sys/contrib/ipfilter/netinet/ip_compat.h14
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil.h6
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c15
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.h4
-rw-r--r--sys/contrib/ipfilter/netinet/ip_state.c18
5 files changed, 51 insertions, 6 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h
index 97c9d7e..daf824c 100644
--- a/sys/contrib/ipfilter/netinet/ip_compat.h
+++ b/sys/contrib/ipfilter/netinet/ip_compat.h
@@ -204,6 +204,8 @@ typedef unsigned int u_32_t;
# define U_32_T 1
# ifdef _KERNEL
+# define NEED_LOCAL_RAND 1
+# define ipf_random arc4random
# define KRWLOCK_T krwlock_t
# define KMUTEX_T kmutex_t
@@ -334,6 +336,7 @@ typedef mblk_t mb_t;
typedef struct uio uio_t;
# endif
typedef int ioctlcmd_t;
+typedef uint8_t u_int8_t;
# define OS_RECOGNISED 1
@@ -564,6 +567,8 @@ typedef struct {
# endif
# ifdef _KERNEL
+# define NEED_LOCAL_RAND 1
+# define ipf_random arc4random
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
(x)++; MUTEX_EXIT(&ipf_rw); }
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
@@ -660,6 +665,8 @@ typedef struct mbuf mb_t;
# include <sys/sysmacros.h>
# ifdef _KERNEL
+# define NEED_LOCAL_RAND 1
+# define ipf_random arc4random
# define KMUTEX_T simple_lock_data_t
# define KRWLOCK_T lock_data_t
# include <net/net_globals.h>
@@ -781,6 +788,8 @@ typedef unsigned int u_32_t;
typedef char * caddr_t;
# endif
+# define ipf_random arc4random
+
# ifdef _KERNEL
# if (__NetBSD_Version__ >= 399001400)
# define KMALLOCS(a, b, c) (a) = (b)malloc((c), _M_IPF, M_NOWAIT)
@@ -820,6 +829,11 @@ typedef u_int32_t u_32_t;
/* F R E E B S D */
/* ----------------------------------------------------------------------- */
#ifdef __FreeBSD__
+# if (__FreeBSD_version < 400000)
+# define NEED_LOCAL_RAND 1
+# else
+# define ipf_random arc4random
+# endif
# if defined(_KERNEL)
# if (__FreeBSD_version >= 500000)
# include "opt_bpf.h"
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index 353328c..0cd84b9 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -1523,6 +1523,12 @@ extern void ipf_freetoken __P((ipftoken_t *));
extern int ipf_deltoken __P((int,int, void *));
extern int ipfsync __P((void));
extern int ipf_genericiter __P((void *, int, void *));
+#ifndef ipf_random
+extern u_32_t ipf_random __P((void));
+#endif
+#ifdef NEED_LOCAL_RAND
+extern void ipf_rand_push __P((void *, int));
+#endif
extern int fr_running;
extern u_long fr_frouteok[2];
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index a696321..8b227e0 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -1678,6 +1678,9 @@ int logtype;
if (logtype != 0 && nat_logging != 0)
nat_log(nat, logtype);
+#if defined(NEED_LOCAL_RAND) && defined(_KERNEL)
+ ipf_rand_push(nat, sizeof(*nat));
+#endif
/*
* Take it as a general indication that all the pointers are set if
@@ -2029,7 +2032,13 @@ natinfo_t *ni;
/*
* Standard port translation. Select next port.
*/
- port = htons(np->in_pnext++);
+ if (np->in_flags & IPN_SEQUENTIAL) {
+ port = htons(np->in_pnext);
+ } else {
+ port = ipf_random() % (ntohs(np->in_pmax) -
+ ntohs(np->in_pmin));
+ }
+ np->in_pnext++;
if (np->in_pnext > ntohs(np->in_pmax)) {
np->in_pnext = ntohs(np->in_pmin);
@@ -3793,7 +3802,7 @@ u_32_t *passp;
READ_ENTER(&ipf_nat);
- if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) &&
+ if (((fin->fin_flx & FI_ICMPERR) != 0) &&
(nat = nat_icmperror(fin, &nflags, NAT_OUTBOUND)))
/*EMPTY*/;
else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin)))
@@ -4088,7 +4097,7 @@ u_32_t *passp;
READ_ENTER(&ipf_nat);
- if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) &&
+ if (((fin->fin_flx & FI_ICMPERR) != 0) &&
(nat = nat_icmperror(fin, &nflags, NAT_INBOUND)))
/*EMPTY*/;
else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin)))
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index 3020eb6..c8581ef 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -256,9 +256,11 @@ typedef struct ipnat {
#define IPN_FIXEDDPORT 0x200000
#define IPN_FINDFORWARD 0x400000
#define IPN_IN 0x800000
+#define IPN_SEQUENTIAL 0x1000000
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\
- IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY)
+ IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\
+ IPN_SEQUENTIAL)
/*
* Values for in_redir
diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c
index aa9192a..6c8b158 100644
--- a/sys/contrib/ipfilter/netinet/ip_state.c
+++ b/sys/contrib/ipfilter/netinet/ip_state.c
@@ -195,6 +195,9 @@ ipstate_t *ips_list = NULL;
/* ------------------------------------------------------------------------ */
int fr_stateinit()
{
+#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL)
+ struct timeval tv;
+#endif
int i;
KMALLOCS(ips_table, ipstate_t **, fr_statesize * sizeof(ipstate_t *));
@@ -205,20 +208,27 @@ int fr_stateinit()
KMALLOCS(ips_seed, u_long *, fr_statesize * sizeof(*ips_seed));
if (ips_seed == NULL)
return -2;
+#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL)
+ tv.tv_sec = 0;
+ GETKTIME(&tv);
+#endif
for (i = 0; i < fr_statesize; i++) {
/*
* XXX - ips_seed[X] should be a random number of sorts.
*/
-#if (__FreeBSD_version >= 400000)
+#if !defined(NEED_LOCAL_RAND) && defined(_KERNEL)
ips_seed[i] = arc4random();
#else
ips_seed[i] = ((u_long)ips_seed + i) * fr_statesize;
- ips_seed[i] ^= 0xa5a55a5a;
+ ips_seed[i] += tv.tv_sec;
ips_seed[i] *= (u_long)ips_seed;
ips_seed[i] ^= 0x5a5aa5a5;
ips_seed[i] *= fr_statemax;
#endif
}
+#if defined(NEED_LOCAL_RAND) && defined(_KERNEL)
+ ipf_rand_push(ips_seed, fr_statesize * sizeof(*ips_seed));
+#endif
/* fill icmp reply type table */
for (i = 0; i <= ICMP_MAXTYPE; i++)
@@ -3028,6 +3038,10 @@ int why;
(void) fr_derefrule(&is->is_rule);
}
+#if defined(NEED_LOCAL_RAND) && defined(_KERNEL)
+ ipf_rand_push(is, sizeof(*is));
+#endif
+
MUTEX_DESTROY(&is->is_lock);
KFREE(is);
ips_num--;
OpenPOWER on IntegriCloud