VirtualBox

Changeset 95831 in vbox for trunk/src/VBox/Runtime/r3/win


Ignore:
Timestamp:
Jul 26, 2022 11:44:36 AM (2 years ago)
Author:
vboxsync
Message:

IPRT/nocrt: More nocrt code needed for VS 2019. Code flow guard works as does stack frame chcking (alloca variants untested). bugref:10261

Location:
trunk/src/VBox/Runtime/r3/win
Files:
3 added
3 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/nocrt-stack-win.asm

    r95830 r95831  
    2626
    2727
     28
     29;*********************************************************************************************************************************
     30;*      Header Files                                                                                                             *
     31;*********************************************************************************************************************************
    2832%include "iprt/asmdefs.mac"
     33%include "iprt/x86.mac"
     34
     35
     36;*********************************************************************************************************************************
     37;*      Structures and Typedefs                                                                                                  *
     38;*********************************************************************************************************************************
     39
     40;; Variable descriptor.
     41struc RTC_VAR_DESC_T
     42        .offFrame               resd 1
     43        .cbVar                  resd 1
     44        alignb                  RTCCPTR_CB
     45        .pszName                RTCCPTR_RES 1
     46endstruc
     47
     48;; Frame descriptor.
     49struc RTC_FRAME_DESC_T
     50        .cVars                  resd 1
     51        alignb                  RTCCPTR_CB
     52        .paVars                 RTCCPTR_RES 1   ; Array of RTC_VAR_DESC_T.
     53endstruc
     54
     55;; An alloca allocation.
     56struc RTC_ALLOCA_ENTRY_T
     57        .uGuard1                resd 1
     58        .pNext                  RTCCPTR_RES 1   ; Misaligned.
     59%if ARCH_BITS == 32
     60        .pNextPad               resd 1
     61%endif
     62        .cb                     RTCCPTR_RES 1   ; Misaligned.
     63%if ARCH_BITS == 32
     64        .cbPad                  resd 1
     65%endif
     66        .auGuard2               resd 3
     67endstruc
     68
     69%ifdef RT_ARCH_X86
     70 %define FASTCALL_NAME(a_Name, a_cbArgs)        @ %+ a_Name %+ @ %+ a_cbArgs
     71%else
     72 %define FASTCALL_NAME(a_Name, a_cbArgs)        NAME(a_Name)
     73%endif
     74
     75
     76;*********************************************************************************************************************************
     77;*      Defined Constants And Macros                                                                                             *
     78;*********************************************************************************************************************************
     79%define VARIABLE_MARKER_PRE     0xcccccccc
     80%define VARIABLE_MARKER_POST    0xcccccccc
     81
     82%define ALLOCA_FILLER_BYTE      0xcc
     83%define ALLOCA_FILLER_32        0xcccccccc
    2984
    3085
     
    3590GLOBALNAME __security_cookie
    3691        dd  0xdeadbeef
    37         dd  0x0c00ffe
    38 
    39 
     92        dd  0x0c00ffe0
     93
     94
     95;*********************************************************************************************************************************
     96;*  External Symbols                                                                                                             *
     97;*********************************************************************************************************************************
    4098BEGINCODE
     99extern NAME(_RTC_StackVarCorrupted)
     100extern NAME(_RTC_SecurityCookieMismatch)
     101
    41102
    42103BEGINPROC __GSHandlerCheck
     
    44105ENDPROC   __GSHandlerCheck
    45106
    46 
     107;;
     108; Probe stack to trigger guard faults.
     109;
     110; @param    eax     Frame size.
     111; @uses     Nothing (because we don't quite now the convention).
     112;
     113ALIGNCODE(32)
    47114BEGINPROC __chkstk
    48         int3
     115        push    xBP
     116        mov     xBP, xSP
     117        pushf
     118        push    xAX
     119        push    xBX
     120
     121        xor     ebx, ebx
     122.again:
     123        sub     xBX, PAGE_SIZE
     124        mov     [xBP + xBX], bl
     125        sub     eax, PAGE_SIZE
     126        jnl     .again
     127
     128        pop     xBX
     129        pop     xAX
     130        popf
     131        leave
     132        ret
    49133ENDPROC   __chkstk
    50134
    51135
    52 BEGINPROC _RTC_AllocaHelper
    53         int3
    54 ENDPROC   _RTC_AllocaHelper
    55 
    56 
    57136BEGINPROC _RTC_InitBase
    58137        int3
     
    60139
    61140
    62 BEGINPROC _RTC_CheckStackVars
    63         int3
    64 ENDPROC   _RTC_CheckStackVars
    65 
    66 
    67 BEGINPROC _RTC_CheckStackVars2
    68         int3
    69 ENDPROC   _RTC_CheckStackVars2
    70 
    71 
    72141BEGINPROC _RTC_Shutdown
    73142        int3
     
    75144
    76145
    77 BEGINPROC __security_check_cookie
    78         int3
    79 ENDPROC   __security_check_cookie
     146
     147
     148;;
     149; Checks stack variable markers.
     150;
     151; This seems to be a regular C function in the CRT, but x86 is conveniently
     152; using the fastcall convention which makes it very similar to amd64.
     153;
     154; We try make this as sleek as possible, leaving all the trouble for when we
     155; find a corrupted stack variable and need to call a C function to complain.
     156;
     157; @param        pStackFrame     The caller RSP/ESP.  [RCX/ECX]
     158; @param        pFrameDesc      Frame descriptor.    [RDX/EDX]
     159;
     160ALIGNCODE(64)
     161BEGINPROC FASTCALL_NAME(_RTC_CheckStackVars, 8)
     162        push    xBP
     163
     164        ;
     165        ; Load the variable count into eax and check that it's not zero.
     166        ;
     167        mov     eax, [xDX + RTC_FRAME_DESC_T.cVars]
     168        test    eax, eax
     169        jz      .return
     170
     171        ;
     172        ; Make edx/rdx point to the current variable and xBP be the frame pointer.
     173        ; The latter frees up xCX for scratch use and incidentally make stack access
     174        ; go via SS instead of DS (mostly irrlevant in 64-bit and 32-bit mode).
     175        ;
     176        mov     xDX, [xDX + RTC_FRAME_DESC_T.paVars]
     177        mov     xBP, xCX
     178
     179        ;
     180        ; Loop thru the variables and check that their markers/fences haven't be
     181        ; trampled over.
     182        ;
     183.next_var:
     184        ; Marker before the variable.
     185%if ARCH_BITS == 64
     186        movsxd  rcx, dword [xDX + RTC_VAR_DESC_T.offFrame]
     187%else
     188        mov     xCX, dword [xDX + RTC_VAR_DESC_T.offFrame]
     189%endif
     190        cmp     dword [xBP + xCX - 4], VARIABLE_MARKER_PRE
     191        jne     .corrupted
     192
     193        ; Marker after the variable.
     194        add     ecx, dword [xDX + RTC_VAR_DESC_T.cbVar]
     195%if ARCH_BITS == 64
     196        movsxd  rcx, ecx
     197%endif
     198        cmp     dword [xBP + xCX], VARIABLE_MARKER_POST
     199        jne     .corrupted
     200
     201        ;
     202        ; Advance to the next variable.
     203        ;
     204.advance:
     205        add     xDX, RTC_VAR_DESC_T_size
     206        dec     eax
     207        jnz     .next_var
     208
     209        ;
     210        ; Return.
     211        ;
     212.return:
     213        pop     xBP
     214        ret
     215
     216        ;
     217        ; Complain about corrupt variable.
     218        ;
     219.corrupted:
     220        push    xAX
     221        push    xDX
     222%ifdef RT_ARCH_AMD64
     223        sub     xSP, 28h
     224        mov     xCX, xBP                ; frame pointer + variable descriptor.
     225%else
     226        push    xBP                     ; save EBP
     227        push    xDX                     ; parameter 2 - variable descriptor
     228        push    xBP                     ; parameter 1 - frame pointer.
     229        lea     xBP, [xSP + 3*xCB]      ; turn it into a frame pointer during the call for better unwind.
     230%endif
     231
     232        call    NAME(_RTC_StackVarCorrupted)
     233
     234%ifdef RT_ARCH_AMD64
     235        add     xSP, 28h
     236%else
     237        add     xSP, xCB * 4            ; parameters
     238        pop     xBP
     239%endif
     240        pop     xDX
     241        pop     xAX
     242        jmp     .advance
     243ENDPROC   FASTCALL_NAME(_RTC_CheckStackVars, 8)
     244
     245
     246;;
     247; Initialize an alloca allocation list entry and add it to it.
     248;
     249; When this is call, presumably _RTC_CheckStackVars2 is used to verify the frame.
     250;
     251; @param        pNewEntry       Pointer to the new entry.               [RCX/ECX]
     252; @param        cbEntry         The entry size, including header.       [RDX/EDX]
     253; @param        ppHead          Pointer to the list head pointer.       [R8/stack]
     254;
     255ALIGNCODE(64)
     256BEGINPROC FASTCALL_NAME(_RTC_AllocaHelper, 12)
     257        ;
     258        ; Check that input isn't NULL or the size isn't zero.
     259        ;
     260        test    xCX, xCX
     261        jz      .return
     262        test    xDX, xDX
     263        jz      .return
     264%if ARCH_BITS == 64
     265        test    r8, r8
     266%else
     267        cmp     dword [xSP + xCB], 0
     268%endif
     269        jz      .return
     270
     271        ;
     272        ; Memset the memory to ALLOCA_FILLER
     273        ;
     274%if ARCH_BITS == 64
     275        mov     r10, rdi                ; save rdi
     276        mov     r11, rcx                ; save pNewEntry
     277%else
     278        push    xDI
     279        push    xCX
     280        cld                             ; paranoia
     281%endif
     282
     283        mov     al, ALLOCA_FILLER_BYTE
     284        mov     xDI, xCX                ; entry pointer
     285        mov     xCX, xDX                ; entry size (in bytes)
     286        rep stosb
     287
     288%if ARCH_BITS == 64
     289        mov     rdi, r10
     290%else
     291        pop     xCX
     292        pop     xDI
     293%endif
     294
     295        ;
     296        ; Fill in the entry and link it as onto the head of the chain.
     297        ;
     298%if ARCH_BITS == 64
     299        mov     [r11 + RTC_ALLOCA_ENTRY_T.cb], xDX
     300        mov     xAX, [r8]
     301        mov     [r11 + RTC_ALLOCA_ENTRY_T.pNext], xAX
     302        mov     [r8], r11
     303%else
     304        mov     [xCX + RTC_ALLOCA_ENTRY_T.cb], xDX
     305        mov     xAX, [xSP + xCB]        ; ppHead
     306        mov     xDX, [xAX]
     307        mov     [xCX + RTC_ALLOCA_ENTRY_T.pNext], xDX
     308        mov     [xAX], xCX
     309%endif
     310
     311.return:
     312%if ARCH_BITS == 64
     313        ret
     314%else
     315        ret     4
     316%endif
     317ENDPROC   FASTCALL_NAME(_RTC_AllocaHelper, 12)
     318
     319
     320;;
     321; Checks if the secuity cookie ok, complaining and terminating if it isn't.
     322;
     323ALIGNCODE(16)
     324BEGINPROC FASTCALL_NAME(__security_check_cookie, 4)
     325        cmp     xCX, [__security_cookie xWrtRIP]
     326        jne     .corrupted
     327        ;; amd64 version checks if the top 16 bits are zero, we skip that for now.
     328        ret
     329
     330.corrupted:
     331%ifdef RT_ARCH_AMD64
     332        jmp     NAME(_RTC_SecurityCookieMismatch)
     333%else
     334        push    ebp
     335        mov     ebp, esp
     336        push    ecx
     337        call    NAME(_RTC_SecurityCookieMismatch)
     338        pop     ecx
     339        leave
     340        ret
     341%endif
     342ENDPROC   FASTCALL_NAME(__security_check_cookie, 4)
    80343
    81344
     
    91354ENDPROC   __report_rangecheckfailure
    92355
    93 
    94 BEGINPROC __guard_dispatch_icall_fptr
    95         int3
    96 ENDPROC   __guard_dispatch_icall_fptr
    97 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette