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:0.154 / U:0.280 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site