On 04/29/2012 01:59 AM, Xi Wang wrote:
> On 32-bit systems, a large `n' would overflow `n * sizeof(u32)' and bypass
> the check ceph_decode_need(p, end, n * sizeof(u32), bad).  It would also
> overflow the subsequent kmalloc() size, leading to out-of-bounds write.

This looks good.

Your previous patch made me look at something else though.  If
you can think of a good solution would you be willing to send a
patch to implement it?  (See below.)  I won't hold up committing
this for it, but I'd like your opinion.

Reviewed-by: Alex Elder <[email protected]>

> Signed-off-by: Xi Wang <[email protected]>
> ---
>  net/ceph/osdmap.c |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
> index f80afc3..774eac6 100644
> --- a/net/ceph/osdmap.c
> +++ b/net/ceph/osdmap.c
> @@ -670,6 +670,9 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)

Just above here we see:
        /* pg_temp */
        ceph_decode_32_safe(p, end, len, bad);
        for (i = 0; i < len; i++) {

We haven't validated "len" here either.  Looking at it I'm not sure
we can do much, but I think we do know a few things should be true:
- (len & (sizeof (u32) - 1)) == 0
- len <= (UINT_MAX / (sizeof (struct ceph_pg) + sizeof (u32)))
    and further, if it's invalid to have a value for pg->len of
    zero, then we can instead assert:
- len <= (UINT_MAX / (sizeof (struct ceph_pg) + 2 * sizeof (u32)))

I don't know if it's that important do do a check like this though.

I appreciate these detail-oriented fixes that you've been sending.

>               ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
>               ceph_decode_copy(p, &pgid, sizeof(pgid));
>               n = ceph_decode_32(p);
> +             err = -EINVAL;
> +             if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
> +                     goto bad;
>               ceph_decode_need(p, end, n * sizeof(u32), bad);
>               err = -ENOMEM;
>               pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);

--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to