summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordhartmei <dhartmei@openbsd.org>2003-01-24 15:05:31 +0000
committerdhartmei <dhartmei@openbsd.org>2003-01-24 15:05:31 +0000
commita0c84f695f6b9668a797c9192d6bdbd124a169d3 (patch)
tree22d05789230cf7b1681d94a1d677e13e7e29dbcf
parentdocument pfctl -vvsq (diff)
downloadwireguard-openbsd-a0c84f695f6b9668a797c9192d6bdbd124a169d3.tar.xz
wireguard-openbsd-a0c84f695f6b9668a797c9192d6bdbd124a169d3.zip
Move the mbuf pullup for TCP options to the beginning of TCP handling,
doing it later can invalidate pointers to mbuf data. This fixes subtle breakage just introduced (with 1.306).
-rw-r--r--sys/net/pf.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 9fe4ea62c83..02a0d4a8a7a 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.308 2003/01/24 11:30:00 dhartmei Exp $ */
+/* $OpenBSD: pf.c,v 1.309 2003/01/24 15:05:31 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1829,11 +1829,9 @@ pf_get_wscale(struct mbuf *m, int off, struct tcphdr *th, sa_family_t af)
u_int8_t *opt, optlen;
u_int8_t wscale = 0;
- hlen = th->th_off * 4;
+ hlen = th->th_off << 2;
if (hlen <= sizeof(*th))
return (0);
- if (!pf_pull_hdr(m, off, th, hlen, NULL, NULL, af))
- return (0);
opt = (u_int8_t *)(th + 1);
hlen -= sizeof(*th);
while (hlen >= 3) {
@@ -4139,6 +4137,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
case IPPROTO_TCP: {
struct tcphdr th;
+ int hlen;
pd.hdr.tcp = &th;
if (!pf_pull_hdr(m, off, &th, sizeof(th),
@@ -4146,7 +4145,13 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
log = action != PF_PASS;
goto done;
}
- pd.p_len = pd.tot_len - off - (th.th_off << 2);
+ hlen = th.th_off << 2;
+ if (hlen > sizeof(th) && !pf_pull_hdr(m, off, &th, hlen,
+ &action, &reason, AF_INET)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ pd.p_len = pd.tot_len - off - hlen;
action = pf_normalize_tcp(dir, ifp, m, 0, off, h, &pd);
if (action == PF_DROP)
break;
@@ -4356,6 +4361,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
case IPPROTO_TCP: {
struct tcphdr th;
+ int hlen;
pd.hdr.tcp = &th;
if (!pf_pull_hdr(m, off, &th, sizeof(th),
@@ -4363,7 +4369,13 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
log = action != PF_PASS;
goto done;
}
- pd.p_len = pd.tot_len - off - (th.th_off << 2);
+ hlen = th.th_off << 2;
+ if (hlen > sizeof(th) && !pf_pull_hdr(m, off, &th, hlen,
+ &action, &reason, AF_INET6)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ pd.p_len = pd.tot_len - off - hlen;
action = pf_normalize_tcp(dir, ifp, m, 0, off, h, &pd);
if (action == PF_DROP)
break;