aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/x25_facilities.c
diff options
context:
space:
mode:
authorMatthew Daley <mattjd@gmail.com>2013-03-19 12:36:48 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-05 10:16:37 -0700
commit7f3ea0c12493c9ff38a13a89bcf08846b50c1f1c (patch)
treef181a309b2e24e76711f3c1193211168fc5f8343 /net/x25/x25_facilities.c
parent21f9f5219401be3815db41e60072a53dadf828b6 (diff)
downloadkernel_samsung_tuna-7f3ea0c12493c9ff38a13a89bcf08846b50c1f1c.zip
kernel_samsung_tuna-7f3ea0c12493c9ff38a13a89bcf08846b50c1f1c.tar.gz
kernel_samsung_tuna-7f3ea0c12493c9ff38a13a89bcf08846b50c1f1c.tar.bz2
x25: Handle undersized/fragmented skbs
commit cb101ed2c3c7c0224d16953fe77bfb9d6c2cb9df upstream. There are multiple locations in the X.25 packet layer where a skb is assumed to be of at least a certain size and that all its data is currently available at skb->data. These assumptions are not checked, hence buffer overreads may occur. Use pskb_may_pull to check these minimal size assumptions and ensure that data is available at skb->data when necessary, as well as use skb_copy_bits where needed. Signed-off-by: Matthew Daley <mattjd@gmail.com> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Andrew Hendry <andrew.hendry@gmail.com> Acked-by: Andrew Hendry <andrew.hendry@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/x25/x25_facilities.c')
-rw-r--r--net/x25/x25_facilities.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index f77e4e7..36384a1 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -44,7 +44,7 @@
int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
{
- unsigned char *p = skb->data;
+ unsigned char *p;
unsigned int len;
*vc_fac_mask = 0;
@@ -60,14 +60,16 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
- if (skb->len < 1)
+ if (!pskb_may_pull(skb, 1))
return 0;
- len = *p++;
+ len = skb->data[0];
- if (len >= skb->len)
+ if (!pskb_may_pull(skb, 1 + len))
return -1;
+ p = skb->data + 1;
+
while (len > 0) {
switch (*p & X25_FAC_CLASS_MASK) {
case X25_FAC_CLASS_A: