Re: [PATCH 2/3] libceph: fix overflow in osdmap_decode()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <elder@xxxxxxxxxxx>

> Signed-off-by: Xi Wang <xi.wang@xxxxxxxxx>
> ---
>  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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux