Bug 694456 (CVE-2011-0905)

Summary: CVE-2011-0905 vino: Out of bounds read flaw by processing certain client tight encoding framebuffer update requests
Product: [Other] Security Response Reporter: Jan Lieskovsky <jlieskov>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: jrusnack, kem, ppisar, security-response-team, than
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-03-05 12:52:09 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 696761, 696762, 696763, 696764, 696766, 696767, 696768, 696769, 696770, 701712, 833986, 888637, 888638    
Bug Blocks: 857251    
Attachments:
Description Flags
Fix ported to libvnserver-0.9.7 none

Description Jan Lieskovsky 2011-04-07 12:50:46 UTC
An out of bounds read flaw was found in the way vino, remote desktop
system for GNOME processed certain framebuffer update requests from
VNC client, when tight encoding was used. An attacker could use this
flaw to send a specially-crafted request to vino, causing it to crash.

Upstream bug report:
[1] https://bugzilla.gnome.org/show_bug.cgi?id=641803 (not public yet)
[2] https://bugzilla.gnome.org/show_bug.cgi?id=641802
    (dedicated to CVE-2011-0904 issue)

Relevant upstream commits (for gnome-2-28, gnome-2-30, gnome-2-32,
gnome-3-0 and master branches):

[2]
http://git.gnome.org/browse/vino/commit/?id=dff52694a384fe95195f2211254026b752d63ec4
[3]
http://git.gnome.org/browse/vino/commit/?id=0c2c9175963fc56bf2af10e42867181332f96ce0
[4]
http://git.gnome.org/browse/vino/commit/?id=e17bd4e369f90748654e31a4867211dc7610975d
[5]
http://git.gnome.org/browse/vino/commit/?id=456dadbb5c5971d3448763a44c05b9ad033e522f
[6]
http://git.gnome.org/browse/vino/commit/?id=8beefcf7792d343c10c919ee0c928c81f73b1279

Comment 4 Jan Lieskovsky 2011-04-07 13:15:03 UTC
This issue affects the versions of the vino package, as shipped
with Red Hat Enterprise Linux 4, 5, and 6.

This issue affects the versions of the vino package, as shipped
with Fedora release of 13 and 14.

--

This issue did NOT affect the version of the libvncserver package,
as shipped with Red Hat Enterprise Linux 6.

This issue did NOT affect the version of the libvncserver package,
as present within EPEL-5 repository.

This issue did NOT affect the versions of the libvncserver package,
as shipped with Fedora release of 13 and 14.

Note: See also comment c#17 of this bug report for further information
      / explanation of conclusions from the above paragraph.

--

This issue affects the versions of the kdenetwork package,
as shipped with Red Hat Enterprise Linux 4 and 5.

This issue did NOT affect the version of the kdenetwork package,
as shipped with Red Hat Enterprise Linux 6.

This issue did NOT affect the version of the kdenetwork package,
as shipped with Fedora release of 13 and 14.

Comment 17 Jan Lieskovsky 2011-05-03 13:51:11 UTC
Analysis from Petr Pisar (Red Hat libvncserver package maintainer) why various
libvncserver package versions, as shipped within different products are not
vulnerable to this flaw:


The libvncserver warning is produced in
rfbserver.c:rfbProcessClientNormalMessage() when converting rectangle
coordinates just after processing client packet of rfbFramebufferUpdateRequest
type:

    case rfbFramebufferUpdateRequest:
        [...]
        if ((n = rfbReadExact(cl, ((char *)&msg) + 1,
                           sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) {
            [...]
        }
        [...]
        /* The values come in based on the scaled screen, we need to convert
         * them to values based on the main screen's coordinate system
         */
       
if(!rectSwapIfLEAndClip(&msg.fur.x,&msg.fur.y,&msg.fur.w,&msg.fur.h,cl))
        {
                rfbLog("Warning, ignoring rfbFramebufferUpdateRequest: "
                    "%dXx%dY-%dWx%dH\n",
                    msg.fur.x, msg.fur.y, msg.fur.w, msg.fur.h);
                return;
        }
        [...]

Not only the rectSwapIfLEAndClip() function converts values from network-order
and scales the coordinates, it also clips requested rectangle (msg.fur members)
to fit into server screen size:

rfbBool rectSwapIfLEAndClip(uint16_t* x,uint16_t* y,uint16_t* w,uint16_t* h,
                rfbClientPtr cl)
{
        /* Convert */
        int x1=Swap16IfLE(*x);
        int y1=Swap16IfLE(*y);
        int w1=Swap16IfLE(*w);
        int h1=Swap16IfLE(*h);

        /* Scale */
        rfbScaledCorrection(cl->scaledScreen, cl->screen, &x1, &y1, &w1, &h1,
            "rectSwapIfLEAndClip");
        *x = x1;
        *y = y1;
        *w = w1;
        *h = h1;

        /* Clip
        rfbLog("Clipping: region(%uXx%uY-%uWx%uH) to screen(%dWx%dH)\n",
                *x, *y, *w, *h,
                cl->screen->width, cl->screen->height);
        */
        if(*w>cl->screen->width-*x)
                *w=cl->screen->width-*x;
        /* possible underflow */
        if(*w>cl->screen->width-*x)
                return FALSE;
        if(*h>cl->screen->height-*y)
                *h=cl->screen->height-*y;
        if(*h>cl->screen->height-*y)
                return FALSE;

        return TRUE;
}

And see the comment /* possible underflow */ (other comments added by me). It
checks whether subtraction result fits into uint16_t. Otherwise it refuse the
conversion and warning is printed and client request is refused. This is the
output I get on server side with the Clipping log line:

Clipping: region(29696Xx32768Y-1Wx30975H) to screen(400Wx300H)
Warning, ignoring rfbFramebufferUpdateRequest: 29696Xx32768Y-36240Wx30975H

The Cliping values correspond to the run_00108.input3 packet content:
$ hexdump -C run_00108.input3
00000000  03 00 74 00 80 00 00 01  78 ff                    |..t.....x.|

03 00 is the request type probably
74 00 (29696) is X coordinate
80 00 (32768) is Y cooridnate
00 01 (1) is Width
78 ff (30975) is Height

Let's look on the clipping code closer and remember the *x and *w are uint16_t:
if(*w>cl->screen->width-*x)
        *w=cl->screen->width-*x;
/* possible underflow */
if(*w>cl->screen->width-*x)
        return FALSE;

If X fits into screen width, then substraction result is not negative and
request width is clamped properly.

If X is out of screen width, then subtraction underruns and *W will be
garbled (as can be seen in my output, 1W → 36240W), but still non-negative
(because unsigned type). However subsequent underrun test will compare garbled
non-negative value to negative subtraction result (the same as former one)
resulting is true condition and causing `return FALSE'.

The same applies to vertical clipping.

Thus I conclude LIBVNCSERVER IS NOT VULNERABLE because it performs the range
check on this place. One can see it's the same equation as in current patch:

+   /* Validate the rectangle given by the update packet. */
+   if (w + x > cl->scaledScreen->width || h + y > cl->scaledScreen->height)
+       goto updateFailed;


-- Petr

Comment 18 Jan Lieskovsky 2011-05-03 16:12:46 UTC
Created vino tracking bugs for this issue

Affects: fedora-all [bug 701712]

Comment 19 Jan Lieskovsky 2011-05-03 16:21:37 UTC
Statement:

(none)

Comment 22 errata-xmlrpc 2013-01-21 22:37:29 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 6

Via RHSA-2013:0169 https://rhn.redhat.com/errata/RHSA-2013-0169.html