diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/sched/act_nat.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index d0386a413e8d..509a2d53a99d 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
| @@ -114,6 +114,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 114 | int egress; | 114 | int egress; |
| 115 | int action; | 115 | int action; |
| 116 | int ihl; | 116 | int ihl; |
| 117 | int noff; | ||
| 117 | 118 | ||
| 118 | spin_lock(&p->tcf_lock); | 119 | spin_lock(&p->tcf_lock); |
| 119 | 120 | ||
| @@ -132,7 +133,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 132 | if (unlikely(action == TC_ACT_SHOT)) | 133 | if (unlikely(action == TC_ACT_SHOT)) |
| 133 | goto drop; | 134 | goto drop; |
| 134 | 135 | ||
| 135 | if (!pskb_may_pull(skb, sizeof(*iph))) | 136 | noff = skb_network_offset(skb); |
| 137 | if (!pskb_may_pull(skb, sizeof(*iph) + noff)) | ||
| 136 | goto drop; | 138 | goto drop; |
| 137 | 139 | ||
| 138 | iph = ip_hdr(skb); | 140 | iph = ip_hdr(skb); |
| @@ -144,7 +146,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 144 | 146 | ||
| 145 | if (!((old_addr ^ addr) & mask)) { | 147 | if (!((old_addr ^ addr) & mask)) { |
| 146 | if (skb_cloned(skb) && | 148 | if (skb_cloned(skb) && |
| 147 | !skb_clone_writable(skb, sizeof(*iph)) && | 149 | !skb_clone_writable(skb, sizeof(*iph) + noff) && |
| 148 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) | 150 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) |
| 149 | goto drop; | 151 | goto drop; |
| 150 | 152 | ||
| @@ -172,9 +174,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 172 | { | 174 | { |
| 173 | struct tcphdr *tcph; | 175 | struct tcphdr *tcph; |
| 174 | 176 | ||
| 175 | if (!pskb_may_pull(skb, ihl + sizeof(*tcph)) || | 177 | if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) || |
| 176 | (skb_cloned(skb) && | 178 | (skb_cloned(skb) && |
| 177 | !skb_clone_writable(skb, ihl + sizeof(*tcph)) && | 179 | !skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) && |
| 178 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 180 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
| 179 | goto drop; | 181 | goto drop; |
| 180 | 182 | ||
| @@ -186,9 +188,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 186 | { | 188 | { |
| 187 | struct udphdr *udph; | 189 | struct udphdr *udph; |
| 188 | 190 | ||
| 189 | if (!pskb_may_pull(skb, ihl + sizeof(*udph)) || | 191 | if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) || |
| 190 | (skb_cloned(skb) && | 192 | (skb_cloned(skb) && |
| 191 | !skb_clone_writable(skb, ihl + sizeof(*udph)) && | 193 | !skb_clone_writable(skb, ihl + sizeof(*udph) + noff) && |
| 192 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 194 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
| 193 | goto drop; | 195 | goto drop; |
| 194 | 196 | ||
| @@ -205,7 +207,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 205 | { | 207 | { |
| 206 | struct icmphdr *icmph; | 208 | struct icmphdr *icmph; |
| 207 | 209 | ||
| 208 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph))) | 210 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + noff)) |
| 209 | goto drop; | 211 | goto drop; |
| 210 | 212 | ||
| 211 | icmph = (void *)(skb_network_header(skb) + ihl); | 213 | icmph = (void *)(skb_network_header(skb) + ihl); |
| @@ -215,7 +217,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 215 | (icmph->type != ICMP_PARAMETERPROB)) | 217 | (icmph->type != ICMP_PARAMETERPROB)) |
| 216 | break; | 218 | break; |
| 217 | 219 | ||
| 218 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph))) | 220 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph) + |
| 221 | noff)) | ||
| 219 | goto drop; | 222 | goto drop; |
| 220 | 223 | ||
| 221 | icmph = (void *)(skb_network_header(skb) + ihl); | 224 | icmph = (void *)(skb_network_header(skb) + ihl); |
| @@ -229,8 +232,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 229 | break; | 232 | break; |
| 230 | 233 | ||
| 231 | if (skb_cloned(skb) && | 234 | if (skb_cloned(skb) && |
| 232 | !skb_clone_writable(skb, | 235 | !skb_clone_writable(skb, ihl + sizeof(*icmph) + |
| 233 | ihl + sizeof(*icmph) + sizeof(*iph)) && | 236 | sizeof(*iph) + noff) && |
| 234 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) | 237 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) |
| 235 | goto drop; | 238 | goto drop; |
| 236 | 239 | ||
