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 /sys | |
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).
Diffstat (limited to 'sys')
-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; |