+--------------------------------------------------------------------+
| XADV-2013007 Linux Kernel bt8xx Video Driver IOCTL Heap Overflow |
+--------------------------------------------------------------------+
Vulnerable versions:
- linux kernel 2.6.18 <=
Testbed: ubuntu
Type: Local
Impact: Critical
Vendor: http:
Author: x90c <geinblues *nospam* gmail dot com>
Site: x90c.org
=========
ABSTRACT:
=========
The bt8xx video driver is a video capture driver. It supports Bt848
Bt849, Bt878, and Bt879.
The bt8xx video driver in the linux kernel has a vulnerability to
occur Integer overflow to the kernel panic. It's at do ioctl code for
bt8xx and copy_from_user() larger user-supplied data to the kernel
heap buffer than kmalloc'd kmem.
I discovered it again.
=========
DETAILS:
=========
(1) v4l2_clip struct .
[~linux-2.6.18/include/linux/videodev2.h]
----
struct v4l2_clip
{
struct v4l2_rect c;
struct v4l2_clip __user *next;
};
----
[~linux/2.6.18/include/linux/videodev.h]
----
struct video_window
{
__u32 x,y;
__u32 width,height;
__u32 chromakey;
__u32 flags;
struct video_clip __user *clips;
int clipcount;
#define VIDEO_WINDOW_INTERLACE 1
#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
#define VIDEO_CLIP_BITMAP -1
#define VIDEO_CLIPMAP_SIZE (128 * 625)
};
----
*clips member varaible of video_window is a pointer.
(2) Do exploit: bttv IOCTL!
[~/linux-2.6.18/drivers/media/video/bt8xx/bttv-driver.c]
----
static int bttv_do_ioctl( struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
case VIDIOCSWIN:
{
struct video_window *win = arg;
struct v4l2_window w2;
if (no_overlay > 0) {
printk ( "VIDIOCSWIN: no_overlay\n" );
return -EINVAL;
}
w2.field = V4L2_FIELD_ANY;
w2.w.left = win->x;
w2.w.top = win->y;
w2.w.width = win->width;
w2.w.height = win->height;
w2.clipcount = win->clipcount;
w2.clips = ( struct v4l2_clip __user *)win->clips;
retval = setup_window(fh, btv, &w2, 0);
----
The ioctl argument to win struct pointer and store the win->clipcount and
win->clips to w2 struct for each. and called vulnerable setup_window().
(3) Result: kernel heap overflow occured.
[~/linux-2.6.18/drivers/media/video/bt8xx/bttv-driver.c]
----
static int setup_window( struct bttv_fh *fh, struct bttv *btv,
struct v4l2_window *win, int fixup)
{
struct v4l2_clip *clips = NULL;
int n,size,retval = 0;
if (NULL == fh->ovfmt)
return -EINVAL;
if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED))
return -EINVAL;
retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup);
if (0 != retval)
return retval;
n = win->clipcount;
size = sizeof (*clips)*(n+4);
clips = kmalloc(size,GFP_KERNEL);
if (NULL == clips)
return -ENOMEM;
if (n > 0) {
if (copy_from_user(clips,win->clips, sizeof ( struct v4l2_clip)*n)) {
kfree(clips);
return -EFAULT;
}
}
----
===============
EXPLOIT CODES:
===============
-
=============
PATCH CODES:
=============
-
===============
VENDOR STATUS:
===============
2013/11/18 - I discovered the security bug.
2013/11/18 - The advisory released on full-disclosure, bugtraq.
============
DISCLAIMER:
============
The authors reserve the right not to be responsible for the topicality,
correctness, completeness or quality of the information provided in this
document. Liability claims regarding damage caused by the use of any information
provided, including any kind of information which is incomplete or incorrect,
will therefore be rejected.
|