diff options
-rw-r--r-- | net/netfilter/xt_TCPOPTSTRIP.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c index 25fd1c4e1eec..1eb1a44bfd3d 100644 --- a/net/netfilter/xt_TCPOPTSTRIP.c +++ b/net/netfilter/xt_TCPOPTSTRIP.c | |||
@@ -30,17 +30,28 @@ static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset) | |||
30 | 30 | ||
31 | static unsigned int | 31 | static unsigned int |
32 | tcpoptstrip_mangle_packet(struct sk_buff *skb, | 32 | tcpoptstrip_mangle_packet(struct sk_buff *skb, |
33 | const struct xt_tcpoptstrip_target_info *info, | 33 | const struct xt_action_param *par, |
34 | unsigned int tcphoff, unsigned int minlen) | 34 | unsigned int tcphoff, unsigned int minlen) |
35 | { | 35 | { |
36 | const struct xt_tcpoptstrip_target_info *info = par->targinfo; | ||
36 | unsigned int optl, i, j; | 37 | unsigned int optl, i, j; |
37 | struct tcphdr *tcph; | 38 | struct tcphdr *tcph; |
38 | u_int16_t n, o; | 39 | u_int16_t n, o; |
39 | u_int8_t *opt; | 40 | u_int8_t *opt; |
41 | int len; | ||
42 | |||
43 | /* This is a fragment, no TCP header is available */ | ||
44 | if (par->fragoff != 0) | ||
45 | return XT_CONTINUE; | ||
40 | 46 | ||
41 | if (!skb_make_writable(skb, skb->len)) | 47 | if (!skb_make_writable(skb, skb->len)) |
42 | return NF_DROP; | 48 | return NF_DROP; |
43 | 49 | ||
50 | len = skb->len - tcphoff; | ||
51 | if (len < (int)sizeof(struct tcphdr) || | ||
52 | tcp_hdr(skb)->doff * 4 > len) | ||
53 | return NF_DROP; | ||
54 | |||
44 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); | 55 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); |
45 | opt = (u_int8_t *)tcph; | 56 | opt = (u_int8_t *)tcph; |
46 | 57 | ||
@@ -76,7 +87,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb, | |||
76 | static unsigned int | 87 | static unsigned int |
77 | tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par) | 88 | tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par) |
78 | { | 89 | { |
79 | return tcpoptstrip_mangle_packet(skb, par->targinfo, ip_hdrlen(skb), | 90 | return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb), |
80 | sizeof(struct iphdr) + sizeof(struct tcphdr)); | 91 | sizeof(struct iphdr) + sizeof(struct tcphdr)); |
81 | } | 92 | } |
82 | 93 | ||
@@ -94,7 +105,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par) | |||
94 | if (tcphoff < 0) | 105 | if (tcphoff < 0) |
95 | return NF_DROP; | 106 | return NF_DROP; |
96 | 107 | ||
97 | return tcpoptstrip_mangle_packet(skb, par->targinfo, tcphoff, | 108 | return tcpoptstrip_mangle_packet(skb, par, tcphoff, |
98 | sizeof(*ipv6h) + sizeof(struct tcphdr)); | 109 | sizeof(*ipv6h) + sizeof(struct tcphdr)); |
99 | } | 110 | } |
100 | #endif | 111 | #endif |