staging: ozwpan: Fix farewell report.
authorRupesh Gujare <rupesh.gujare@atmel.com>
Mon, 5 Aug 2013 11:28:33 +0000 (12:28 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Aug 2013 21:02:58 +0000 (14:02 -0700)
This patch fix following issues reported by Dan:-

1) There is no check limiting the size to 32 and it could be up to
   253 bytes.
2) Use defines instead of magic numbers.
3) The oz_farewell struct is supposed to be a variable length struct
   but the variable part is put in the middle.  It doesn't make any
   sense to put the length of the variable size array after then end
   of the array because we can never find it again!  Put the
   variable size array at the end.  Make it a zero length array.
   u8 len;
   u8 report[0];
4) In oz_add_farewell() we do this:

f = kmalloc(sizeof(struct oz_farewell) + len - 1, GFP_ATOMIC);

    The "- 1" refers to sizeof(f->report) but because it was a magic
    number then it was missed when the sizeof(f->report) changed.
5) In [patch 6/6] we set the ->len member.  But because it is at the
   end of a variable length array with no limit check the remote
   attacker can just rewrite it using the memcpy() on the next line.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Rupesh Gujare <rupesh.gujare@atmel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/ozwpan/ozpd.h
drivers/staging/ozwpan/ozproto.c

index 57e98c897711e79a35e838d329c5498f3858f3aa..996ef65ed315652fa25cf4a5e81684991b59033c 100644 (file)
@@ -48,8 +48,8 @@ struct oz_farewell {
        struct list_head link;
        u8 ep_num;
        u8 index;
-       u8 report[32];
        u8 len;
+       u8 report[0];
 };
 
 /* Data structure that holds information on a specific peripheral device (PD).
index 084307a1083f19cea99329e0160f0e8c57b7fc06..3d1a89f073552e4c72094df291f851ed70e23000 100644 (file)
@@ -291,7 +291,7 @@ static void oz_add_farewell(struct oz_pd *pd, u8 ep_num, u8 index,
        struct oz_farewell *f;
        struct oz_farewell *f2;
        int found = 0;
-       f = kmalloc(sizeof(struct oz_farewell) + len - 1, GFP_ATOMIC);
+       f = kmalloc(sizeof(struct oz_farewell) + len, GFP_ATOMIC);
        if (!f)
                return;
        f->ep_num = ep_num;