aboutsummaryrefslogtreecommitdiff
path: root/sys/netipsec
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2003-08-13 22:36:24 +0000
committerSam Leffler <sam@FreeBSD.org>2003-08-13 22:36:24 +0000
commit4dbc6e51dfb79c33afa66d1911c8570ea3c12e0f (patch)
treead3dccfc964194f0b4c01d94d0af9b76c55ee24f /sys/netipsec
parent2692bb26d4a4071834ad9927c9f2d32bd83335fb (diff)
downloadsrc-4dbc6e51dfb79c33afa66d1911c8570ea3c12e0f.tar.gz
src-4dbc6e51dfb79c33afa66d1911c8570ea3c12e0f.zip
make sure the packets contains a complete inner header
for ip{4,6}-in-ip{4,6} encapsulation; fixes panic for truncated ip-in-ip over ipsec Submitted by: Markus Friedl <markus@openbsd.org> Obtained from: OpenBSD (rev 1.66 ipsec_input.c)
Notes
Notes: svn path=/head/; revision=118888
Diffstat (limited to 'sys/netipsec')
-rw-r--r--sys/netipsec/ipsec_input.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c
index fb64a05547d0..17e52182b60a 100644
--- a/sys/netipsec/ipsec_input.c
+++ b/sys/netipsec/ipsec_input.c
@@ -323,6 +323,13 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
if (prot == IPPROTO_IPIP) {
struct ip ipn;
+ if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
+ IPSEC_ISTAT(sproto, espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ error = EINVAL;
+ goto bad;
+ }
/* ipn will now contain the inner IPv4 header */
m_copydata(m, ip->ip_hl << 2, sizeof(struct ip),
(caddr_t) &ipn);
@@ -362,6 +369,13 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
if (prot == IPPROTO_IPV6) {
struct ip6_hdr ip6n;
+ if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
+ IPSEC_ISTAT(sproto, espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ error = EINVAL;
+ goto bad;
+ }
/* ip6n will now contain the inner IPv6 header. */
m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr),
(caddr_t) &ip6n);
@@ -633,6 +647,13 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto
if (prot == IPPROTO_IPIP) {
struct ip ipn;
+ if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
+ IPSEC_ISTAT(sproto, espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ error = EINVAL;
+ goto bad;
+ }
/* ipn will now contain the inner IPv4 header */
m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
@@ -668,6 +689,13 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto
if (prot == IPPROTO_IPV6) {
struct ip6_hdr ip6n;
+ if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
+ IPSEC_ISTAT(sproto, espstat.esps_hdrops,
+ ahstat.ahs_hdrops,
+ ipcompstat.ipcomps_hdrops);
+ error = EINVAL;
+ goto bad;
+ }
/* ip6n will now contain the inner IPv6 header. */
m_copydata(m, skip, sizeof(struct ip6_hdr),
(caddr_t) &ip6n);