lkml.org 
[lkml]   [2001]   [Jul]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [CHECKER] 52 probable security holes in 2.4.6 and 2.4.6-ac2
    Kenneth Michael Ashcraft wrote:

    >
    > [BUG] but mainly can make the kernel allocate unbounded amount of
    > memory and crash.
    > /home/kash/linux/2.4.6/drivers/char/drm/ioctl.c:90:drm_setunique: ERROR:RANGE:82:90: Using user length "unique_len" as argument to "copy_from_user" [type=LOCAL] [state = tainted] [linkages -> 88:unique_len=unique_len -> 88:u->unique_len -> 82:u:start] [distance=25]
    > drm_unique_t u;
    >
    > if (dev->unique_len || dev->unique)
    > return -EBUSY;
    >
    > Start --->
    > if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u)))
    > return -EFAULT;
    >
    > if (!u.unique_len)
    > return -EINVAL;
    >
    > dev->unique_len = u.unique_len;
    > dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
    > Error --->
    > if (copy_from_user(dev->unique, u.unique, dev->unique_len))
    > return -EFAULT;
    > dev->unique[dev->unique_len] = '\0';


    This is not a bug. This is a root only ioctl called only during Xserver
    initialization/recycle. It can't be called anywhere else.

    >
    >
    >
    > [BUG] unchecked int [should print this out in the message]
    > /home/kash/linux/2.4.6/drivers/char/drm/i810_dma.c:1419:i810_copybuf: ERROR:RANGE:1411:1419: Using user length "used" as argument to "copy_from_user" [type=LOCAL] [state = tainted] set by 'copy_from_user':1419 [linkages -> 1419:d->used -> 1411:d:start] [distance=46]
    > if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
    > DRM_ERROR("i810_dma called without lock held\n");
    > return -EINVAL;
    > }
    >
    > Start --->
    > if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
    > return -EFAULT;
    >
    > if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
    > buf = dma->buflist[ d.idx ];
    > buf_priv = buf->dev_private;
    > if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
    >
    > Error --->
    > if (copy_from_user(buf_priv->virtual, d.address, d.used))
    > return -EFAULT;
    >
    > sarea_priv->last_dispatch = (int) hw_status[5];

    I'll send in a patch for this one. Its really a bug.

    >
    > ---------------------------------------------------------
    > [BUG] you could loop for a long time.
    > /home/kash/linux/2.4.6/drivers/char/drm/mga_bufs.c:485:mga_freebufs: ERROR:RANGE:482:485: [LOOP] Looping on user length "count" set by 'copy_from_user':485 [linkages -> 485:request->count -> 482:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_free_t *)arg,
    > Start --->
    > sizeof(request)))
    > return -EFAULT;
    >
    > Error --->
    > for (i = 0; i < request.count; i++) {
    > if (copy_from_user(&idx,
    > &request.list[i],
    > sizeof(idx)))
    > ---------------------------------------------------------
    > [BUG] you could loop for a long time.
    > /home/kash/linux/2.4.6/drivers/char/drm/bufs.c:435:drm_freebufs: ERROR:RANGE:431:435: [LOOP] Looping on user length "count" set by 'copy_from_user':434 [linkages -> 434:request->count -> 431:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_free_t *)arg,
    > Start --->
    > sizeof(request)))
    > return -EFAULT;
    >
    > DRM_DEBUG("%d\n", request.count);
    > Error --->
    > for (i = 0; i < request.count; i++) {
    > if (copy_from_user(&idx,
    > &request.list[i],
    > sizeof(idx)))
    > ---------------------------------------------------------
    > [BUG] you could loop for a long time.
    > /home/kash/linux/2.4.6/drivers/char/drm/i810_bufs.c:311:i810_freebufs: ERROR:RANGE:307:311: [LOOP] Looping on user length "count" set by 'copy_from_user':310 [linkages -> 310:request->count -> 307:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_free_t *)arg,
    > Start --->
    > sizeof(request)))
    > return -EFAULT;
    >
    > DRM_DEBUG("%d\n", request.count);
    > Error --->
    > for (i = 0; i < request.count; i++) {
    > if (copy_from_user(&idx,
    > &request.list[i],
    > sizeof(idx)))
    > ---------------------------------------------------------


    These are not bugs. The maximum this loop can ever be is dma->buf_count.
    drm_free_buffer will set the owner pid to zero, and if (buf->pid !=
    current->pid) we exit the loop.

    >
    > [BUG] no direct check on count
    > /home/kash/linux/2.4.6/drivers/char/drm/i810_bufs.c:104:i810_addbufs_agp: ERROR:RANGE:61:104: [LOOP] Looping on user length "count" [linkages -> 64:count=count -> 64:request->count -> 61:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_desc_t *)arg,
    > Start --->
    > sizeof(request)))
    >
    > ... DELETED 37 lines ...
    >
    >
    > entry->buf_size = size;
    > entry->page_order = page_order;
    > offset = 0;
    >
    > Error --->
    > while(entry->buf_count < count) {
    > buf = &entry->buflist[entry->buf_count];
    > buf->idx = dma->buf_count + entry->buf_count;
    > buf->total = alignment;
    > ---------------------------------------------------------
    > [BUG] no direct check on count
    > /home/kash/linux/2.4.6/drivers/char/drm/mga_bufs.c:115:mga_addbufs_agp: ERROR:RANGE:62:115: [LOOP] Looping on user length "count" [linkages -> 65:count=count -> 65:request->count -> 62:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_desc_t *)arg,
    > Start --->
    > sizeof(request)))
    >
    > ... DELETED 47 lines ...
    >
    > entry->buf_size = size;
    > entry->page_order = page_order;
    > offset = 0;
    >
    >
    > Error --->
    > while(entry->buf_count < count) {
    > buf = &entry->buflist[entry->buf_count];
    > buf->idx = dma->buf_count + entry->buf_count;
    > buf->total = alignment;
    > ---------------------------------------------------------
    > [BUG] no direct check on count
    > /home/kash/linux/2.4.6/drivers/char/drm/radeon_bufs.c:116:radeon_addbufs_agp: ERROR:RANGE:62:116: [LOOP] Looping on user length "count" [linkages -> 65:count=count -> 65:request->count -> 62:request:start]
    > int byte_count;
    > int i;
    >
    > if (!dma) return -EINVAL;
    >
    > Start --->
    > if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
    >
    > ... DELETED 48 lines ...
    >
    >
    > entry->buf_size = size;
    > entry->page_order = page_order;
    > offset = 0;
    >
    > Error --->
    > for (offset = 0;
    > entry->buf_count < count;
    > offset += alignment, ++entry->buf_count) {
    > buf = &entry->buflist[entry->buf_count];
    > ---------------------------------------------------------
    > [BUG] no direct check on count
    > /home/kash/linux/2.4.6/drivers/char/drm/r128_bufs.c:119:r128_addbufs_agp: ERROR:RANGE:65:119: [LOOP] Looping on user length "count" [linkages -> 68:count=count -> 68:request->count -> 65:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_desc_t *)arg,
    > Start --->
    > sizeof(request)))
    >
    > ... DELETED 48 lines ...
    >
    >
    > entry->buf_size = size;
    > entry->page_order = page_order;
    > offset = 0;
    >
    > Error --->
    > for (offset = 0;
    > entry->buf_count < count;
    > offset += alignment, ++entry->buf_count) {
    > buf = &entry->buflist[entry->buf_count];
    > ---------------------------------------------------------
    > [BUG] no direct check on count
    > /home/kash/linux/2.4.6/drivers/char/drm/mga_bufs.c:287:mga_addbufs_pci: ERROR:RANGE:220:287: [LOOP] Looping on user length "count" [linkages -> 223:count=count -> 223:request->count -> 220:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_desc_t *)arg,
    > Start --->
    > sizeof(request)))
    >
    > ... DELETED 61 lines ...
    >
    >
    > entry->buf_size = size;
    > entry->page_order = page_order;
    > byte_count = 0;
    > page_count = 0;
    > Error --->
    > while (entry->buf_count < count) {
    > if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) break;
    > entry->seglist[entry->seg_count++] = page;
    > for (i = 0; i < (1 << page_order); i++) {
    > ---------------------------------------------------------
    > [BUG] no direct check on count
    > /home/kash/linux/2.4.6/drivers/char/drm/bufs.c:239:drm_addbufs: ERROR:RANGE:172:239: [LOOP] Looping on user length "count" [linkages -> 175:count=count -> 175:request->count -> 172:request:start]
    >
    > if (!dma) return -EINVAL;
    >
    > if (copy_from_user(&request,
    > (drm_buf_desc_t *)arg,
    > Start --->
    > sizeof(request)))
    >
    > ... DELETED 61 lines ...
    >
    >
    > entry->buf_size = size;
    > entry->page_order = page_order;
    > byte_count = 0;
    > page_count = 0;
    > Error --->
    > while (entry->buf_count < count) {
    > if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) break;
    > entry->seglist[entry->seg_count++] = page;
    > for (i = 0; i < (1 << page_order); i++) {
    > ---------------------------------------------------------
    >

    These are not bugs, they are root only ioctl's.

    -Jeff

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 12:57    [W:2.664 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site