aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/skbuff.h7
-rw-r--r--include/net/sock.h1
-rw-r--r--net/core/skbuff.c8
-rw-r--r--net/core/stream.c1
4 files changed, 17 insertions, 0 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c4619a428d9b..f8f234708b98 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -344,6 +344,13 @@ extern void skb_over_panic(struct sk_buff *skb, int len,
344 void *here); 344 void *here);
345extern void skb_under_panic(struct sk_buff *skb, int len, 345extern void skb_under_panic(struct sk_buff *skb, int len,
346 void *here); 346 void *here);
347extern void skb_truesize_bug(struct sk_buff *skb);
348
349static inline void skb_truesize_check(struct sk_buff *skb)
350{
351 if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
352 skb_truesize_bug(skb);
353}
347 354
348extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, 355extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
349 int getfrag(void *from, char *to, int offset, 356 int getfrag(void *from, char *to, int offset,
diff --git a/include/net/sock.h b/include/net/sock.h
index af2b0544586e..ff8b0dad7b0f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -454,6 +454,7 @@ static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk)
454 454
455static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb) 455static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
456{ 456{
457 skb_truesize_check(skb);
457 sock_set_flag(sk, SOCK_QUEUE_SHRUNK); 458 sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
458 sk->sk_wmem_queued -= skb->truesize; 459 sk->sk_wmem_queued -= skb->truesize;
459 sk->sk_forward_alloc += skb->truesize; 460 sk->sk_forward_alloc += skb->truesize;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 09464fa8d72f..fb3770f9c094 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -112,6 +112,14 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
112 BUG(); 112 BUG();
113} 113}
114 114
115void skb_truesize_bug(struct sk_buff *skb)
116{
117 printk(KERN_ERR "SKB BUG: Invalid truesize (%u) "
118 "len=%u, sizeof(sk_buff)=%Zd\n",
119 skb->truesize, skb->len, sizeof(struct sk_buff));
120}
121EXPORT_SYMBOL(skb_truesize_bug);
122
115/* Allocate a new skbuff. We do this ourselves so we can fill in a few 123/* Allocate a new skbuff. We do this ourselves so we can fill in a few
116 * 'private' fields and also do memory statistics to find all the 124 * 'private' fields and also do memory statistics to find all the
117 * [BEEP] leaks. 125 * [BEEP] leaks.
diff --git a/net/core/stream.c b/net/core/stream.c
index 35e25259fd95..e9489696f694 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -176,6 +176,7 @@ void sk_stream_rfree(struct sk_buff *skb)
176{ 176{
177 struct sock *sk = skb->sk; 177 struct sock *sk = skb->sk;
178 178
179 skb_truesize_check(skb);
179 atomic_sub(skb->truesize, &sk->sk_rmem_alloc); 180 atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
180 sk->sk_forward_alloc += skb->truesize; 181 sk->sk_forward_alloc += skb->truesize;
181} 182}