diff options
author | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2003-01-24 15:05:32 +0000 |
---|---|---|
committer | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2003-01-24 15:05:32 +0000 |
commit | 3f52dd692f93a3208316575b2b8f7f1ff93b8caf (patch) | |
tree | 99da7292aa5d130e8bec742896ebc13c2975a392 | |
parent | 114f657fb7fef852528b044f091e7241231ef8e5 (diff) |
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.c | 24 |
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; |