summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Pfatschbacher <mpf@cvs.openbsd.org>2011-10-16 21:07:20 +0000
committerMarco Pfatschbacher <mpf@cvs.openbsd.org>2011-10-16 21:07:20 +0000
commit7134aba0ef997beae0023b69d5bb90ac114a0829 (patch)
treed8e20b1ab97580c95f0505566e6281841d824ec8
parent268508182a25e1d313a66f4df679cbfbb70d5eed (diff)
Use m_pullup() instead of IP6_EXTHDR_GET() to get the carp header
in the v6 input path. IP6_EXTHDR_GET() internally uses m_pulldown(), which might return a pointer to a different mbuf in the chain. In this case, carp_cksum() will be called with the wrong mbuf. This fixes occasional checksum mismatches. Problem found and initial fix by stsp@ OK stsp@
-rw-r--r--sys/netinet/ip_carp.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 56e4ca7f6d6..2337fbe9a9a 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.190 2011/09/06 16:00:22 mpf Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.191 2011/10/16 21:07:19 mpf Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -650,13 +650,12 @@ carp6_proto_input(struct mbuf **mp, int *offp, int proto)
/* verify that we have a complete carp packet */
len = m->m_len;
- IP6_EXTHDR_GET(ch, struct carp_header *, m, *offp, sizeof(*ch));
- if (ch == NULL) {
+ if ((m = m_pullup(m, *offp + sizeof(*ch))) == NULL) {
carpstats.carps_badlen++;
CARP_LOG(LOG_INFO, sc, ("packet size %u too small", len));
return (IPPROTO_DONE);
}
-
+ ch = (struct carp_header *)(mtod(m, caddr_t) + *offp);
/* verify the CARP checksum */
m->m_data += *offp;