VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/compiler/vcc/stack-except-vcc.cpp@ 96420

Last change on this file since 96420 was 96420, checked in by vboxsync, 3 years ago

IPRT/nocrt: Implemented GSHandlerCheck so we can avoid overrunning the stack due to the int3 in the stub. bugref:10261

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.2 KB
Line 
1/* $Id: stack-except-vcc.cpp 96420 2022-08-23 02:14:54Z vboxsync $ */
2/** @file
3 * IPRT - Visual C++ Compiler - Stack Checking, __GSHandlerCheck.
4 */
5
6/*
7 * Copyright (C) 2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.215389.xyz.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include "internal/nocrt.h"
42
43#include <iprt/win/windows.h>
44
45#include <iprt/asm.h>
46#include <iprt/asm-amd64-x86.h>
47#ifndef IPRT_NOCRT_WITHOUT_FATAL_WRITE
48# include <iprt/assert.h>
49#endif
50
51#include "internal/compiler-vcc.h"
52#include "except-vcc.h"
53
54
55#if !defined(RT_ARCH_AMD64)
56# error "This file is for AMD64 (and probably ARM, but needs porting)"
57#endif
58
59
60
61/**
62 * Check the stack cookie before calling the exception handler.
63 *
64 * This is to prevent attackers from bypassing stack cookie checking by
65 * triggering an exception.
66 *
67 * This does not call any C++ exception handlers, as it's probably (still
68 * figuring this stuff out) only used when C++ exceptions are disabled.
69 *
70 * @returns Exception disposition.
71 * @param pXcptRec The exception record.
72 * @param pXcptRegRec The exception registration record, taken to be the frame
73 * address.
74 * @param pCpuCtx The CPU context for the exception.
75 * @param pDispCtx Dispatcher context.
76 */
77extern "C" __declspec(guard(suppress))
78EXCEPTION_DISPOSITION __GSHandlerCheck(PEXCEPTION_RECORD pXcptRec, PEXCEPTION_REGISTRATION_RECORD pXcptRegRec,
79 PCONTEXT pCpuCtx, PDISPATCHER_CONTEXT pDispCtx)
80{
81 RT_NOREF(pXcptRec, pCpuCtx);
82
83 /*
84 * Locate the stack cookie and call the regular stack cookie checker routine.
85 */
86 PCGS_HANDLER_DATA pHandlerData = (PCGS_HANDLER_DATA)pDispCtx->HandlerData;
87
88 /* Calculate the cookie address and read it. */
89 uintptr_t uPtrFrame = (uintptr_t)pXcptRegRec;
90 uint32_t offCookie = pHandlerData->u.offCookie;
91 if (offCookie & GS_HANDLER_OFF_COOKIE_HAS_ALIGNMENT)
92 {
93 uPtrFrame += pHandlerData->offAlignedBase;
94 uPtrFrame &= ~(uintptr_t)pHandlerData->uAlignmentMask;
95 }
96 uintptr_t uCookie = *(uintptr_t const *)(uPtrFrame + (int32_t)(offCookie & GS_HANDLER_OFF_COOKIE_MASK));
97
98 /* The stored cookie is xor'ed with the frame / registration record address
99 or with the frame pointer register if one is being used. In the latter
100 case, we have to add the frame offset to get the correct address. */
101 uintptr_t uXorAddr = (uintptr_t)pXcptRegRec;
102 PCIMAGE_UNWIND_INFO pUnwindInfo = (PCIMAGE_UNWIND_INFO)(pDispCtx->ImageBase + pDispCtx->FunctionEntry->UnwindInfoAddress);
103 if (pUnwindInfo->FrameRegister != 0)
104 uXorAddr += pUnwindInfo->FrameOffset << 4;
105
106 /* This call will not return on failure. */
107 __security_check_cookie(uCookie ^ uXorAddr);
108
109 return ExceptionContinueSearch;
110}
111
Note: See TracBrowser for help on using the repository browser.

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