diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-07-25 04:46:46 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-08-01 05:45:15 -0400 |
commit | a206bcb3b02025b23137f3228109d72e0f835c05 (patch) | |
tree | 517502da0639006d869a3d407d78132c5acb3dea /net | |
parent | 71ffe9c77dd7a2b62207953091efa8dafec958dd (diff) |
netfilter: xt_TCPOPTSTRIP: fix possible off by one access
Fix a possible off by one access since optlen()
touches opt[offset+1] unsafely when i == tcp_hdrlen(skb) - 1.
This patch replaces tcp_hdrlen() by the local variable tcp_hdrlen
that stores the TCP header length, to save some cycles.
Reported-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/xt_TCPOPTSTRIP.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c index b68fa191710f..625fa1d636a0 100644 --- a/net/netfilter/xt_TCPOPTSTRIP.c +++ b/net/netfilter/xt_TCPOPTSTRIP.c | |||
@@ -38,7 +38,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb, | |||
38 | struct tcphdr *tcph; | 38 | struct tcphdr *tcph; |
39 | u_int16_t n, o; | 39 | u_int16_t n, o; |
40 | u_int8_t *opt; | 40 | u_int8_t *opt; |
41 | int len; | 41 | int len, tcp_hdrlen; |
42 | 42 | ||
43 | /* This is a fragment, no TCP header is available */ | 43 | /* This is a fragment, no TCP header is available */ |
44 | if (par->fragoff != 0) | 44 | if (par->fragoff != 0) |
@@ -52,7 +52,9 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb, | |||
52 | return NF_DROP; | 52 | return NF_DROP; |
53 | 53 | ||
54 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); | 54 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); |
55 | if (tcph->doff * 4 > len) | 55 | tcp_hdrlen = tcph->doff * 4; |
56 | |||
57 | if (len < tcp_hdrlen) | ||
56 | return NF_DROP; | 58 | return NF_DROP; |
57 | 59 | ||
58 | opt = (u_int8_t *)tcph; | 60 | opt = (u_int8_t *)tcph; |
@@ -61,10 +63,10 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb, | |||
61 | * Walk through all TCP options - if we find some option to remove, | 63 | * Walk through all TCP options - if we find some option to remove, |
62 | * set all octets to %TCPOPT_NOP and adjust checksum. | 64 | * set all octets to %TCPOPT_NOP and adjust checksum. |
63 | */ | 65 | */ |
64 | for (i = sizeof(struct tcphdr); i < tcp_hdrlen(skb); i += optl) { | 66 | for (i = sizeof(struct tcphdr); i < tcp_hdrlen - 1; i += optl) { |
65 | optl = optlen(opt, i); | 67 | optl = optlen(opt, i); |
66 | 68 | ||
67 | if (i + optl > tcp_hdrlen(skb)) | 69 | if (i + optl > tcp_hdrlen) |
68 | break; | 70 | break; |
69 | 71 | ||
70 | if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i])) | 72 | if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i])) |