summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/icmp_var.h3
-rw-r--r--sys/netinet/ip_icmp.c3
-rw-r--r--sys/netinet6/udp6_usrreq.c36
3 files changed, 38 insertions, 4 deletions
diff --git a/sys/netinet/icmp_var.h b/sys/netinet/icmp_var.h
index f7bfa8b..dda84f2 100644
--- a/sys/netinet/icmp_var.h
+++ b/sys/netinet/icmp_var.h
@@ -82,7 +82,8 @@ extern int badport_bandlim(int);
#define BANDLIM_ICMP_TSTAMP 2
#define BANDLIM_RST_CLOSEDPORT 3 /* No connection, and no listeners */
#define BANDLIM_RST_OPENPORT 4 /* No connection, listener */
-#define BANDLIM_MAX 4
+#define BANDLIM_ICMP6_UNREACH 5
+#define BANDLIM_MAX 5
#endif
#endif
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index b330699..36cc020 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -888,7 +888,8 @@ badport_bandlim(int which)
{ "icmp ping response" },
{ "icmp tstamp response" },
{ "closed port RST response" },
- { "open port RST response" }
+ { "open port RST response" },
+ { "icmp6 unreach response" }
};
/*
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 2772f24..b57448b 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -65,6 +65,7 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
+#include "opt_mac.h"
#include <sys/param.h>
#include <sys/errno.h>
@@ -92,7 +93,9 @@
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
#include <netinet/ip6.h>
+#include <netinet/icmp_var.h>
#include <netinet/icmp6.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
@@ -108,6 +111,8 @@
#include <netipsec/ipsec6.h>
#endif /* IPSEC */
+#include <security/mac/mac_framework.h>
+
/*
* UDP protocol inplementation.
* Per RFC 768, August, 1980.
@@ -133,7 +138,12 @@ udp6_append(struct inpcb *in6p, struct mbuf *n, int off,
return;
}
#endif /* IPSEC */
-
+#ifdef MAC
+ if (mac_check_inpcb_deliver(in6p, n) != 0) {
+ m_freem(n);
+ return;
+ }
+#endif
opts = NULL;
if (in6p->in6p_flags & IN6P_CONTROLOPTS ||
in6p->inp_socket->so_options & SO_TIMESTAMP)
@@ -184,6 +194,12 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
udpstat.udps_ipackets++;
+ /*
+ * Destination port of 0 is illegal, based on RFC768.
+ */
+ if (uh->uh_dport == 0)
+ goto badunlocked;
+
plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
ulen = ntohs((u_short)uh->uh_ulen);
@@ -235,6 +251,15 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
continue;
if (in6p->in6p_lport != uh->uh_dport)
continue;
+ /*
+ * XXX: Do not check source port of incoming datagram
+ * unless inp_connect() has been called to bind the
+ * fport part of the 4-tuple; the source could be
+ * trying to talk to us with an ephemeral port.
+ */
+ if (in6p->inp_fport != 0 &&
+ in6p->inp_fport != uh->uh_sport)
+ continue;
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr,
&ip6->ip6_dst))
@@ -310,6 +335,10 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
goto badheadlocked;
}
INP_INFO_RUNLOCK(&udbinfo);
+ if (udp_blackhole)
+ goto badunlocked;
+ if (badport_bandlim(BANDLIM_ICMP6_UNREACH) < 0)
+ goto badunlocked;
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
return (IPPROTO_DONE);
}
@@ -318,6 +347,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
INP_UNLOCK(in6p);
INP_INFO_RUNLOCK(&udbinfo);
return (IPPROTO_DONE);
+
badheadlocked:
INP_INFO_RUNLOCK(&udbinfo);
badunlocked:
@@ -735,7 +765,9 @@ udp6_send(struct socket *so, int flags, struct mbuf *m,
}
}
#endif
-
+#ifdef MAC
+ mac_create_mbuf_from_inpcb(inp, m);
+#endif
error = udp6_output(inp, m, addr, control, td);
out:
INP_UNLOCK(inp);
OpenPOWER on IntegriCloud