diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2004-08-23 01:30:31 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2004-08-23 01:30:31 +0000 |
commit | a9c251a960035b82b2189cd58bcac626f30ed7fc (patch) | |
tree | ebdc169c29fa771fb707a9dc1e1511c063f30684 /sys/netinet6/raw_ip6.c | |
parent | 6f4d4977dba9d4e594f67b71246c95afd005a6f2 (diff) |
make sure we do not overwrite checksum field on shared mbuf.
markus, henning, deraadt, mcbride ok
Diffstat (limited to 'sys/netinet6/raw_ip6.c')
-rw-r--r-- | sys/netinet6/raw_ip6.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index f05ef964280..5bbab8ca444 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.27 2004/06/12 04:58:48 itojun Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.28 2004/08/23 01:30:30 itojun Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -459,8 +459,10 @@ rip6_output(struct mbuf *m, ...) if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 || in6p->in6p_cksum != -1) { + struct mbuf *n; int off; - u_int16_t sum; + u_int16_t *sump; + int sumoff; /* compute checksum */ if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) @@ -473,10 +475,15 @@ rip6_output(struct mbuf *m, ...) } off += sizeof(struct ip6_hdr); - sum = 0; - m_copyback(m, off, sizeof(sum), &sum); - sum = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen); - m_copyback(m, off, sizeof(sum), &sum); + n = m_pulldown(m, off, sizeof(*sump), &sumoff); + if (n == NULL) { + m = NULL; + error = ENOBUFS; + goto bad; + } + sump = (u_int16_t *)(mtod(n, caddr_t) + sumoff); + *sump = 0; + *sump = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen); } flags = 0; |