diff options
| author | Patrick McHardy <kaber@trash.net> | 2006-11-14 22:48:09 -0500 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-11-16 00:18:48 -0500 |
| commit | d8a585d78efdf191a64ca655136ac1e49fd27cf4 (patch) | |
| tree | 5effa2c2ec3a46fef6aaee1b7484d10318970d0e | |
| parent | 7fdeaf68a16f8102659cf1b30f57247d8ccbeef0 (diff) | |
[NETFILTER]: Use pskb_trim in {ip,ip6,nfnetlink}_queue
Based on patch by James D. Nurmi:
I've got some code very dependant on nfnetlink_queue, and turned up a
large number of warns coming from skb_trim. While it's quite possibly
my code, having not seen it on older kernels made me a bit suspect.
Anyhow, based on some googling I turned up this thread:
http://lkml.org/lkml/2006/8/13/56
And believe the issue to be related, so attached is a small patch to
the kernel -- not sure if this is completely correct, but for anyone
else hitting the WARN_ON(1) in skbuff.h, it might be helpful..
Signed-off-by: James D. Nurmi <jdnurmi@gmail.com>
Ported to ip6_queue and nfnetlink_queue and added return value
checks.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 7 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_queue.c | 7 |
3 files changed, 12 insertions, 9 deletions
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 7edad790478a..97556cc2e4e0 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -351,9 +351,10 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
| 351 | if (v->data_len < sizeof(*user_iph)) | 351 | if (v->data_len < sizeof(*user_iph)) |
| 352 | return 0; | 352 | return 0; |
| 353 | diff = v->data_len - e->skb->len; | 353 | diff = v->data_len - e->skb->len; |
| 354 | if (diff < 0) | 354 | if (diff < 0) { |
| 355 | skb_trim(e->skb, v->data_len); | 355 | if (pskb_trim(e->skb, v->data_len)) |
| 356 | else if (diff > 0) { | 356 | return -ENOMEM; |
| 357 | } else if (diff > 0) { | ||
| 357 | if (v->data_len > 0xFFFF) | 358 | if (v->data_len > 0xFFFF) |
| 358 | return -EINVAL; | 359 | return -EINVAL; |
| 359 | if (diff > skb_tailroom(e->skb)) { | 360 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 9510c24ca8d2..9fec832ee08b 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
| @@ -349,9 +349,10 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
| 349 | if (v->data_len < sizeof(*user_iph)) | 349 | if (v->data_len < sizeof(*user_iph)) |
| 350 | return 0; | 350 | return 0; |
| 351 | diff = v->data_len - e->skb->len; | 351 | diff = v->data_len - e->skb->len; |
| 352 | if (diff < 0) | 352 | if (diff < 0) { |
| 353 | skb_trim(e->skb, v->data_len); | 353 | if (pskb_trim(e->skb, v->data_len)) |
| 354 | else if (diff > 0) { | 354 | return -ENOMEM; |
| 355 | } else if (diff > 0) { | ||
| 355 | if (v->data_len > 0xFFFF) | 356 | if (v->data_len > 0xFFFF) |
| 356 | return -EINVAL; | 357 | return -EINVAL; |
| 357 | if (diff > skb_tailroom(e->skb)) { | 358 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 6e4ada3c1844..e815a9aa6e95 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
| @@ -622,9 +622,10 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e) | |||
| 622 | int diff; | 622 | int diff; |
| 623 | 623 | ||
| 624 | diff = data_len - e->skb->len; | 624 | diff = data_len - e->skb->len; |
| 625 | if (diff < 0) | 625 | if (diff < 0) { |
| 626 | skb_trim(e->skb, data_len); | 626 | if (pskb_trim(e->skb, data_len)) |
| 627 | else if (diff > 0) { | 627 | return -ENOMEM; |
| 628 | } else if (diff > 0) { | ||
| 628 | if (data_len > 0xFFFF) | 629 | if (data_len > 0xFFFF) |
| 629 | return -EINVAL; | 630 | return -EINVAL; |
| 630 | if (diff > skb_tailroom(e->skb)) { | 631 | if (diff > skb_tailroom(e->skb)) { |
