Bug 159414 (CVE-2016-4762) - Uninitialized variable in DIBPixelData can cause a dangerous memory write
Summary: Uninitialized variable in DIBPixelData can cause a dangerous memory write
Status: RESOLVED FIXED
Alias: CVE-2016-4762
Product: WebKit
Classification: Unclassified
Component: WebKit Misc. (show other bugs)
Version: WebKit Local Build
Hardware: PC Windows 7
: P2 Critical
Assignee: Per Arne Vollan
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2016-07-05 01:36 PDT by Zheng Huang
Modified: 2017-10-11 10:28 PDT (History)
3 users (show)

See Also:


Attachments
poc and analysis and debug code (278.18 KB, application/octet-stream)
2016-07-05 01:36 PDT, Zheng Huang
no flags Details
Patch (5.94 KB, patch)
2016-07-14 10:01 PDT, Per Arne Vollan
bfulgham: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Zheng Huang 2016-07-05 01:36:35 PDT
Created attachment 282757 [details]
poc and analysis and debug code

void DIBPixelData::setRGBABitmapAlpha(HDC hdc, const IntRect& dstRect, unsigned char level)
{    
HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)); // hdc=NULL, so bitmap=NULL
    DIBPixelData pixelData(bitmap);    // when bitmap=NULL, initialize pixelData failed

	ASSERT(pixelData.bitsPerPixel() == 32);

    IntRect drawRect(dstRect);
    XFORM trans;
    GetWorldTransform(hdc, &trans);
    IntSize transformedPosition(trans.eDx, trans.eDy);
    drawRect.move(transformedPosition);

    int pixelDataWidth = pixelData.size().width();    // read from initialize failed pixelData object
    int pixelDataHeight = pixelData.size().height();   // read from initialize failed pixelData object
    IntRect bitmapRect(0, 0, pixelDataWidth, pixelDataHeight);
    drawRect.intersect(bitmapRect);
    if (drawRect.isEmpty())
        return;

    RGBQUAD* bytes = reinterpret_cast<RGBQUAD*>(pixelData.buffer());
    bytes += drawRect.y() * pixelDataWidth;    //bytes tainted by pixelDataWidth

    size_t width = drawRect.width();
    size_t height = drawRect.height();
	
    int x = drawRect.x();
    for (size_t i = 0; i < height; i++) {
        RGBQUAD* p = bytes + x;    //p tainted by bytes
        for (size_t j = 0; j < width; j++) {
            p->rgbReserved = level;     -------------------- crash here, write to uninitialized memory
            p++;
        }
        bytes += pixelDataWidth;
    }
}
Comment 1 Radar WebKit Bug Importer 2016-07-13 09:15:54 PDT
<rdar://problem/27324600>
Comment 2 Per Arne Vollan 2016-07-14 10:01:59 PDT
Created attachment 283653 [details]
Patch
Comment 3 Brent Fulgham 2016-07-14 10:07:26 PDT
Comment on attachment 283653 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=283653&action=review

r+, but please revise the title a little to read more clearly. Also, can you make some clarifying statements about what constitutes a passing or failing test? Do we crash or something in the original "unfixed" case?

> Source/WebCore/ChangeLog:3
> +        DIBPixelData use uninitialized variable cause dangerous memory write

Can we rephrase this:

Uninitialized variable in DIBPixelData can cause a dangerous memory write

> Tools/TestWebKitAPI/Tests/WebCore/win/DIBPixelData.cpp:38
> +    DIBPixelData::setRGBABitmapAlpha(nullptr, IntRect(), 0);

How do we know if this test passes? Do we get a crash before your fix? Or if we run with DebugMalloc do we get an error in the original code case?
Comment 4 Per Arne Vollan 2016-07-14 13:44:27 PDT
(In reply to comment #3)
> Comment on attachment 283653 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=283653&action=review
> 
> r+, but please revise the title a little to read more clearly. Also, can you
> make some clarifying statements about what constitutes a passing or failing
> test? Do we crash or something in the original "unfixed" case?
> 
> > Source/WebCore/ChangeLog:3
> > +        DIBPixelData use uninitialized variable cause dangerous memory write
> 
> Can we rephrase this:
> 
> Uninitialized variable in DIBPixelData can cause a dangerous memory write
> 
> > Tools/TestWebKitAPI/Tests/WebCore/win/DIBPixelData.cpp:38
> > +    DIBPixelData::setRGBABitmapAlpha(nullptr, IntRect(), 0);
> 
> How do we know if this test passes? Do we get a crash before your fix? Or if
> we run with DebugMalloc do we get an error in the original code case?

Yes, the test would crash before the fix.

Thanks for reviewing! I will update the patch accordingly before landing :)
Comment 5 Per Arne Vollan 2016-07-15 05:45:51 PDT
Committed r203274: <https://trac.webkit.org/changeset/203274>
Comment 6 Zheng Huang 2016-07-18 19:33:49 PDT
Hi, I want to ask about this bug, is that I can get a CVE for this bug and get an acknowledgment by apple?
Comment 7 Brent Fulgham 2016-07-18 22:48:25 PDT
(In reply to comment #6)
> Hi, I want to ask about this bug, is that I can get a CVE for this bug and
> get an acknowledgment by apple?

I'll talk to Product Security and have someone contact you directly. Thank you for filing the bug!
Comment 8 Zheng Huang 2016-08-08 01:25:20 PDT
Hi,Brent Fulgham,nobody contact me for 20 days for this bug, is it normal?