Changeset 51770 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Jul 1, 2014 6:14:02 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 23 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/bird/hardenedwindows (added) merged: 92692-94610
- Property svn:mergeinfo changed
-
trunk/src/VBox
- Property svn:mergeinfo changed
/branches/bird/hardenedwindows/src/VBox (added) merged: 92692-94610
- Property svn:mergeinfo changed
-
trunk/src/VBox/HostDrivers/Support/Makefile.kmk
r51346 r51770 31 31 # Targets 32 32 # 33 LIBRARIES += SUPR3 SUPR3Static SUPR3HardenedStatic 33 LIBRARIES += SUPR3 SUPR3Static 34 ifdef VBOX_WITH_HARDENING 35 LIBRARIES += SUPR3HardenedStatic 36 endif 37 DLLS.win += VBoxSupLib 34 38 ifdef VBOX_WITH_32_ON_64_MAIN_API 35 39 LIBRARIES += SUPR3-x86 … … 70 74 endif # !VBOX_ONLY_DOCS && !VBOX_ONLY_EXTPACKS && !VBOX_ONLY_VALIDATIONKIT 71 75 76 # 77 # Authenticode related trust anchors and certificates -> .cpp 78 # 79 VBOX_SUP_WIN_CERTS_FILE = $(SUPR3_0_OUTDIR)/TrustAnchorsAndCerts.cpp 80 VBOX_SUP_WIN_CERTS := \ 81 SpcRootMicrosoft0=SpcRoot-MicrosoftAuthenticodeTmRootAuthority-01.taf \ 82 SpcRootMicrosoft1=SpcRoot-MicrosoftRootAuthority-00c1008b3c3c8811d13ef663ecdf40.taf \ 83 SpcRootMicrosoft2=SpcRoot-MicrosoftRootCertificateAuthority-79ad16a14aa0a5ad4c7358f407132e65.taf \ 84 SpcRootMicrosoft3=SpcRoot-MicrosoftRootCertificateAuthority2010-28cc3a25bfba44ac449a9b586b4339aa.taf \ 85 SpcRootMicrosoft4=SpcRoot-MicrosoftRootCertificateAuthority2011-3f8bc8b5fc9fb29643b569d66c42e144.taf \ 86 SpcRootMicrosoft5=SpcRoot-MicrosoftDigitalMediaAuthority2005-6eff330eb6e7569740680870104baaba.taf \ 87 NtRootMicrosoft6=NtRoot-MicrosoftCodeVerificationRoot-729404101f3e0ca347837fca175a8438.taf \ 88 TimeRootMicrosoft0=Timestamp-CopyrightC1997MicrosoftCorp-01.taf \ 89 TrustedCertVBox0=Trusted-OracleCorporationVirtualBox-51ca009816fdbd80f120e015ee75823e.taf 90 VBOX_SUP_WIN_CERT_NAMES := $(foreach cert,$(VBOX_SUP_WIN_CERTS),$(firstword $(subst =,$(SPACE) ,$(cert)))) 91 VBOX_PATH_SUPR3_CERTIFICATES := $(PATH_SUB_CURRENT)/win/Certificates 92 93 # 1=name, 2=filter, 3=buildcert?. 94 if "$(KBUILD_TARGET)" == "win" && defined(VBOX_WITH_HARDENING) 95 VBOX_SUP_GEN_CERT_MACRO = 'SUPTAENTRY const g_aSUP$(1)TAs[] =' '{' \ 96 $(if-expr "$(3)" == "",,' SUPTAENTRY_GEN(g_abSUPBuildCert),') \ 97 $(foreach certnm,$(filter $(2),$(VBOX_SUP_WIN_CERT_NAMES)), ' SUPTAENTRY_GEN(g_abSUP$(certnm)),') \ 98 '};' 'unsigned const g_cSUP$(1)TAs = RT_ELEMENTS(g_aSUP$(1)TAs);' '' '' 99 else 100 VBOX_SUP_GEN_CERT_MACRO = 'SUPTAENTRY const g_aSUP$(1)TAs[] =' '{' \ 101 $(foreach certnm,$(filter $(2),$(VBOX_SUP_WIN_CERT_NAMES)), ' SUPTAENTRY_GEN(g_abSUP$(certnm)),') \ 102 '};' 'unsigned const g_cSUP$(1)TAs = RT_ELEMENTS(g_aSUP$(1)TAs);' '' '' 103 endif 104 105 $$(VBOX_SUP_WIN_CERTS_FILE): $(MAKEFILE_CURRENT) \ 106 $(foreach cert,$(VBOX_SUP_WIN_CERTS),$(VBOX_PATH_SUPR3_CERTIFICATES)/$(lastword $(subst =,$(SPACE) ,$(cert)))) \ 107 $(VBOX_BIN2C) \ 108 $(if-expr "$(KBUILD_TARGET)" == "win" && defined(VBOX_WITH_HARDENING),$(VBOX_RTSIGNTOOL)) \ 109 | $$(dir $$@) 110 $(QUIET)$(RM) -f -- $@ [email protected] 111 $(QUIET)$(APPEND) -n "$@" \ 112 '' \ 113 '#include <VBox/sup.h>' \ 114 '' 115 $(foreach cert,$(VBOX_SUP_WIN_CERTS), $(NLTAB)$(VBOX_BIN2C) -ascii --append \ 116 "SUP$(firstword $(subst =,$(SP) ,$(cert)))" \ 117 "$(VBOX_PATH_SUPR3_CERTIFICATES)/$(lastword $(subst =,$(SP) ,$(cert)))" \ 118 "$@") 119 # The build certificate. 120 if "$(KBUILD_TARGET)" == "win" && defined(VBOX_WITH_HARDENING) 121 $(VBOX_RTSIGNTOOL) extract-exe-signer-cert --exe $(VBOX_RTSIGNTOOL) --output "[email protected]" --der 122 $(VBOX_BIN2C) -ascii --append SUPBuildCert "[email protected]" $@ 123 $(QUIET)$(RM) -f -- [email protected] 124 endif 125 # Generate certificate lists. 126 $(QUIET)$(APPEND) -n "$@" '' \ 127 $(call VBOX_SUP_GEN_CERT_MACRO,All,%,build) \ 128 $(call VBOX_SUP_GEN_CERT_MACRO,SpcRoot,SpcRoot%) \ 129 $(call VBOX_SUP_GEN_CERT_MACRO,NtKernelRoot,NtRoot%) \ 130 $(call VBOX_SUP_GEN_CERT_MACRO,Timestamp,TimeRoot%) \ 131 $(call VBOX_SUP_GEN_CERT_MACRO,Trusted,TrustedCert%,build) 132 133 tst: $(VBOX_SUP_WIN_CERTS_FILE) 134 72 135 73 136 # 74 137 # The Ring-3 Support Library (this is linked into the IPRT dll, VBoxRT). 75 138 # 76 SUPR3_TEMPLATE = VBOXR3NP139 SUPR3_TEMPLATE = VBOXR3NP 77 140 SUPR3_DEFS = \ 78 141 IN_SUP_R3 IN_RT_R3 \ … … 88 151 SUPR3HardenedIPRT.cpp \ 89 152 SUPR3HardenedVerify.cpp \ 90 $(KBUILD_TARGET)/SUPLib-$(KBUILD_TARGET).cpp 153 $(KBUILD_TARGET)/SUPLib-$(KBUILD_TARGET).cpp \ 154 $(VBOX_SUP_WIN_CERTS_FILE) 155 ifdef VBOX_WITH_HARDENING 156 SUPR3_SOURCES.win = \ 157 win/SUPHardenedVerifyImage-win.cpp 158 endif 91 159 92 160 SUPR3-x86_TEMPLATE = VBoxR3Dll-x86 … … 95 163 96 164 # 97 # Static version of SUPR3. 165 # Static version of SUPR3. This is more of a stub than anything else in a 166 # hardened build, at least on windows. 98 167 # 99 168 SUPR3Static_TEMPLATE = VBOXR3STATIC 100 169 SUPR3Static_EXTENDS = SUPR3 170 SUPR3Static_DEFS = $(SUPR3_DEFS) IN_SUP_R3_STATIC 171 SUPR3Static_SOURCES.win = $(filter-out win/SUPHardenedVerifyImage-win.cpp, $(SUPR3_SOURCES.win)) 172 101 173 102 174 # 103 175 # The static part of the hardened support library (ring-3). 104 176 # 177 VBOX_PATH_RUNTIME_SRC ?= $(PATH_ROOT)/src/VBox/Runtime 105 178 SUPR3HardenedStatic_TEMPLATE = VBOXR3HARDENEDLIB 106 179 SUPR3HardenedStatic_DEFS = IN_SUP_HARDENED_R3 … … 108 181 $(if $(VBOX_WITH_SUPSVC),VBOX_WITH_SUPSVC,) \ 109 182 $(if $(VBOX_WITH_MAIN),VBOX_WITH_MAIN,) \ 110 $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) 183 $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \ 184 $(if $(VBOX_WITHOUT_DEBUGGER_CHECKS),VBOX_WITHOUT_DEBUGGER_CHECKS,) 185 ifdef VBOX_WITH_VISTA_NO_SP 186 SUPR3HardenedStatic_DEFS.win += VBOX_WITH_VISTA_NO_SP 187 endif 111 188 SUPR3HardenedStatic_INCS = . 112 189 SUPR3HardenedStatic_SOURCES = \ 113 190 SUPR3HardenedMain.cpp \ 114 191 SUPR3HardenedVerify.cpp \ 192 SUPR3HardenedNoCrt.cpp \ 115 193 $(KBUILD_TARGET)/SUPLib-$(KBUILD_TARGET).cpp 194 SUPR3HardenedStatic_SOURCES.win = \ 195 win/SUPR3HardenedMain-win.cpp \ 196 win/SUPR3HardenedMainA-win.asm \ 197 win/SUPHardenedVerifyProcess-win.cpp \ 198 win/SUPHardenedVerifyImage-win.cpp \ 199 $(VBOX_SUP_WIN_CERTS_FILE) 200 201 if1of ($(KBUILD_TARGET),win) ## @todo some of this move up. 202 SUPR3HardenedStatic_SDKS += VBoxOpenSslHardened 203 SUPR3HardenedStatic_DEFS += IN_RT IN_RT_R3 IN_RT_STATIC IPRT_NO_CRT RT_WITH_NOCRT_ALIASES LOG_DISABLED IPRT_NO_ERROR_DATA 204 SUPR3HardenedStatic_DEFS.win += LDR_ONLY_PE __STRALIGN_H_ 205 206 SUPR3HardenedStatic_INCS += $(PATH_ROOT)/include/iprt/nocrt $(VBOX_PATH_RUNTIME_SRC)/include 207 208 SUPR3HardenedStatic_SOURCES += \ 209 $(VBOX_PATH_RUNTIME_SRC)/common/ldr/ldr.cpp \ 210 $(VBOX_PATH_RUNTIME_SRC)/common/ldr/ldrEx.cpp \ 211 $(VBOX_PATH_RUNTIME_SRC)/common/ldr/ldrPE.cpp \ 212 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-basics.cpp \ 213 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-cursor.cpp \ 214 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-default-allocator.cpp \ 215 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-dump.cpp \ 216 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-encode.cpp \ 217 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-bitstring.cpp \ 218 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-bitstring-decode.cpp \ 219 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-boolean.cpp \ 220 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-boolean-decode.cpp \ 221 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-core.cpp \ 222 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-core-decode.cpp \ 223 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-dyntype.cpp \ 224 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-dyntype-decode.cpp \ 225 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-integer.cpp \ 226 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-integer-decode.cpp \ 227 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-null.cpp \ 228 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-null-decode.cpp \ 229 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-objid.cpp \ 230 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-objid-decode.cpp \ 231 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-octetstring.cpp \ 232 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-octetstring-decode.cpp \ 233 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-string.cpp \ 234 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-string-decode.cpp \ 235 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-time.cpp \ 236 $(VBOX_PATH_RUNTIME_SRC)/common/asn1/asn1-ut-time-decode.cpp \ 237 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/digest-core.cpp \ 238 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/digest-builtin.cpp \ 239 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkcs7-asn1-decoder.cpp \ 240 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkcs7-core.cpp \ 241 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkcs7-init.cpp \ 242 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkcs7-sanity.cpp \ 243 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkcs7-verify.cpp \ 244 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkix-signature-builtin.cpp \ 245 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkix-signature-core.cpp \ 246 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkix-signature-rsa.cpp \ 247 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkix-verify.cpp \ 248 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/pkix-util.cpp \ 249 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/rsa-asn1-decoder.cpp \ 250 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/rsa-core.cpp \ 251 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/rsa-init.cpp \ 252 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/rsa-sanity.cpp \ 253 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/spc-asn1-decoder.cpp \ 254 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/spc-core.cpp \ 255 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/spc-init.cpp \ 256 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/spc-sanity.cpp \ 257 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/x509-asn1-decoder.cpp \ 258 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/x509-certpaths.cpp \ 259 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/x509-core.cpp \ 260 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/x509-init.cpp \ 261 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/x509-sanity.cpp \ 262 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/x509-verify.cpp \ 263 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/store.cpp \ 264 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/store-inmem.cpp \ 265 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/taf-asn1-decoder.cpp \ 266 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/taf-core.cpp \ 267 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/taf-init.cpp \ 268 $(VBOX_PATH_RUNTIME_SRC)/common/crypto/taf-sanity.cpp \ 269 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/md2.cpp \ 270 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/md5.cpp \ 271 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/sha1.cpp \ 272 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/sha256.cpp \ 273 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/sha512.cpp \ 274 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/md2str.cpp \ 275 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/md5str.cpp \ 276 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/sha1str.cpp \ 277 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/sha256str.cpp \ 278 $(VBOX_PATH_RUNTIME_SRC)/common/checksum/sha512str.cpp \ 279 $(VBOX_PATH_RUNTIME_SRC)/common/err/errinfo.cpp \ 280 $(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathChangeToUnixSlashes.cpp \ 281 $(VBOX_PATH_RUNTIME_SRC)/common/path/RTPathExt.cpp \ 282 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrPrintHexBytes.cpp \ 283 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16PrintHexBytes.cpp \ 284 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTUtf16ICmpAscii.cpp \ 285 $(VBOX_PATH_RUNTIME_SRC)/common/string/strstrip.cpp \ 286 \ 287 $(VBOX_PATH_RUNTIME_SRC)/common/err/errmsg.cpp \ 288 $(VBOX_PATH_RUNTIME_SRC)/common/math/bignum.cpp \ 289 $(VBOX_PATH_RUNTIME_SRC)/common/misc/RTAssertMsg1Weak.cpp \ 290 $(VBOX_PATH_RUNTIME_SRC)/common/misc/RTAssertMsg2Weak.cpp \ 291 $(VBOX_PATH_RUNTIME_SRC)/common/misc/RTAssertMsg2WeakV.cpp \ 292 $(VBOX_PATH_RUNTIME_SRC)/common/string/memchr.asm \ 293 $(VBOX_PATH_RUNTIME_SRC)/common/string/memcmp.asm \ 294 $(VBOX_PATH_RUNTIME_SRC)/common/string/memcpy.asm \ 295 $(VBOX_PATH_RUNTIME_SRC)/common/string/memmove.asm \ 296 $(VBOX_PATH_RUNTIME_SRC)/common/string/mempcpy.asm \ 297 $(VBOX_PATH_RUNTIME_SRC)/common/string/memset.asm \ 298 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrCat.cpp \ 299 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrCmp.cpp \ 300 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrCopy.cpp \ 301 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrNCmp.cpp \ 302 $(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrNLen.cpp \ 303 $(VBOX_PATH_RUNTIME_SRC)/common/string/strchr.asm \ 304 $(VBOX_PATH_RUNTIME_SRC)/common/string/strcmp.asm \ 305 $(VBOX_PATH_RUNTIME_SRC)/common/string/strcpy.asm \ 306 $(VBOX_PATH_RUNTIME_SRC)/common/string/strformat.cpp \ 307 $(VBOX_PATH_RUNTIME_SRC)/common/string/strformatrt.cpp \ 308 $(VBOX_PATH_RUNTIME_SRC)/common/string/strformattype.cpp \ 309 $(VBOX_PATH_RUNTIME_SRC)/common/string/stringalloc.cpp \ 310 $(VBOX_PATH_RUNTIME_SRC)/common/string/strlen.asm \ 311 $(VBOX_PATH_RUNTIME_SRC)/common/string/strncmp.asm \ 312 $(VBOX_PATH_RUNTIME_SRC)/common/string/strncpy.asm \ 313 $(VBOX_PATH_RUNTIME_SRC)/common/string/strprintf.cpp \ 314 $(VBOX_PATH_RUNTIME_SRC)/common/string/strtonum.cpp \ 315 $(VBOX_PATH_RUNTIME_SRC)/common/string/utf-16.cpp \ 316 $(VBOX_PATH_RUNTIME_SRC)/common/string/utf-8.cpp \ 317 $(VBOX_PATH_RUNTIME_SRC)/common/string/utf-8-case.cpp \ 318 $(VBOX_PATH_RUNTIME_SRC)/common/string/unidata-upper.cpp \ 319 $(VBOX_PATH_RUNTIME_SRC)/common/string/unidata-lower.cpp \ 320 $(VBOX_PATH_RUNTIME_SRC)/common/time/time.cpp \ 321 $(VBOX_PATH_RUNTIME_SRC)/generic/RTAssertShouldPanic-generic.cpp \ 322 $(VBOX_PATH_RUNTIME_SRC)/generic/memsafer-generic.cpp \ 323 $(VBOX_PATH_RUNTIME_SRC)/generic/uuid-generic.cpp \ 324 325 326 SUPR3HardenedStatic_SOURCES.win += \ 327 win/SUPR3HardenedNoCrt-win.cpp \ 328 $(VBOX_PATH_RUNTIME_SRC)/nt/RTErrConvertFromNtStatus.cpp \ 329 $(VBOX_PATH_RUNTIME_SRC)/win/RTErrConvertFromWin32.cpp \ 330 $(VBOX_PATH_RUNTIME_SRC)/win/errmsgwin.cpp 331 332 # Add necessary compiler specific files from libcmt.lib and the lib dir. 333 ifeq ($(KBUILD_TARGET),win) 334 SUPR3HardenedStatic_VBOX_LIBC_OBJS = chkstk.obj 335 ifeq ($(KBUILD_TARGET_ARCH),x86) 336 SUPR3HardenedStatic_VBOX_LIBC_OBJS += alloca16.obj 337 endif 338 SUPR3HardenedStatic_SOURCES.win += $(addprefix $(SUPR3HardenedStatic_0_OUTDIR)/,$(SUPR3HardenedStatic_VBOX_LIBC_OBJS)) 339 340 $(addprefix $$(SUPR3HardenedStatic_0_OUTDIR)/,$(SUPR3HardenedStatic_VBOX_LIBC_OBJS)): \ 341 $$(PATH_TOOL_$(TEMPLATE_VBOXR3EXE_TOOL.win.$(KBUILD_TARGET_ARCH))_LIB)/libcmt.lib | $$(dir $$@) 342 $(TOOL_$(TEMPLATE_VBOXR3HARDENEDEXE_TOOL.win.$(KBUILD_TARGET_ARCH))_AR) "$<" \ 343 /EXTRACT:`$(TOOL_$(TEMPLATE_VBOXR3HARDENEDEXE_TOOL.win.$(KBUILD_TARGET_ARCH))_AR) "$<" /LIST \ 344 | $(SED_EXT) -n -e '/$(notdir $@)/p'` \ 345 "/OUT:$@" 346 endif 347 endif 348 349 350 # 351 # VBoxSupLib - Windows DLL for catching thread creation and termination. 352 # 353 VBoxSupLib_TEMPLATE = $(if "$(KBUILD_TARGET)" == "win",VBOXR3HARDENEDLIB,VBOXR3) 354 VBoxSupLib_LDFLAGS.win.amd64 = -Entry:DllMainEntrypoint 355 VBoxSupLib_LDFLAGS.win.x86 = -Entry:DllMainEntrypoint 356 VBoxSupLib_DEFS = \ 357 $(if $(VBOX_WITHOUT_DEBUGGER_CHECKS),VBOX_WITHOUT_DEBUGGER_CHECKS,) 358 VBoxSupLib_SOURCES = \ 359 $(KBUILD_TARGET)/VBoxSupLib-$(KBUILD_TARGET).cpp 360 VBoxSupLib_LIBS.win = \ 361 $(SUPR3HardenedStatic_1_INS_TARGET) 362 116 363 117 364 # … … 263 510 VBoxDrv_DEBUG_INST.darwin= $(patsubst %/,%,$(INST_VBOXDRV)) 264 511 VBoxDrv_SDKS.win = ReorderCompilerIncs $(VBOX_WINDDK) $(VBOX_WINPSDK)INCS 512 ifdef VBOX_WITH_HARDENING 513 VBoxDrv_SDKS.win += VBoxOpenSslHardened 514 endif 265 515 266 516 VBoxDrv_DEFS := IN_RT_R0 IN_SUP_R0 SUPDRV_WITH_RELEASE_LOGGER VBOX_SVN_REV=$(VBOX_SVN_REV) 267 517 ifdef VBOX_WITH_DTRACE_R0DRV 268 518 VBoxDrv_DEFS += VBOX_WITH_DTRACE VBOX_WITH_DTRACE_R0DRV 519 endif 520 ifdef VBOX_WITHOUT_DEBUGGER_CHECKS 521 VBoxDrv_DEFS += VBOX_WITHOUT_DEBUGGER_CHECKS 269 522 endif 270 523 #VBoxDrv_DEFS.debug += DEBUG_DARWIN_GIP … … 284 537 VBoxDrv_DEFS.win += VBOX_WITHOUT_NATIVE_R0_LOADER 285 538 endif 539 ifdef VBOX_WITH_VISTA_NO_SP 540 VBoxDrv_DEFS.win += VBOX_WITH_VISTA_NO_SP 541 endif 286 542 287 543 VBoxDrv_INCS = . $(VBoxDrv_0_OUTDIR) … … 292 548 VBoxDrv_LIBS.linux.debug = $(VBoxDrv_LIBS) $(VBOX_GCC_LIBGCC) 293 549 VBoxDrv_LIBS.win = \ 550 $(PATH_STAGE_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) \ 294 551 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/ntoskrnl.lib \ 295 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/hal.lib \ 296 $(PATH_STAGE_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) 552 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/hal.lib 297 553 298 554 #VBoxDrv_LDFLAGS.darwin = -v -Wl,-whyload -Wl,-v -Wl,-whatsloaded … … 314 570 win/SUPDrvA-win.asm \ 315 571 win/VBoxDrv.rc 572 ifdef VBOX_WITH_HARDENING 573 VBoxDrv_SOURCES.win += \ 574 win/SUPHardenedVerifyImage-win.cpp \ 575 win/SUPHardenedVerifyProcess-win.cpp \ 576 $(VBOX_SUP_WIN_CERTS_FILE) 577 endif 316 578 VBoxDrv_SOURCES = \ 317 579 SUPDrv.d \ -
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r51718 r51770 464 464 * Initialize it. 465 465 */ 466 memset(pDevExt, 0, sizeof(*pDevExt)); 466 memset(pDevExt, 0, sizeof(*pDevExt)); /* Does not wipe OS specific tail section of the structure. */ 467 pDevExt->Spinlock = NIL_RTSPINLOCK; 468 pDevExt->hGipSpinlock = NIL_RTSPINLOCK; 469 pDevExt->hSessionHashTabSpinlock = NIL_RTSPINLOCK; 467 470 rc = RTSpinlockCreate(&pDevExt->Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "SUPDrvDevExt"); 468 471 if (RT_SUCCESS(rc)) 469 {470 472 rc = RTSpinlockCreate(&pDevExt->hGipSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "SUPDrvGip"); 473 if (RT_SUCCESS(rc)) 474 rc = RTSpinlockCreate(&pDevExt->hSessionHashTabSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "SUPDrvSession"); 475 476 if (RT_SUCCESS(rc)) 477 #ifdef SUPDRV_USE_MUTEX_FOR_LDR 478 rc = RTSemMutexCreate(&pDevExt->mtxLdr); 479 #else 480 rc = RTSemFastMutexCreate(&pDevExt->mtxLdr); 481 #endif 482 if (RT_SUCCESS(rc)) 483 { 484 rc = RTSemFastMutexCreate(&pDevExt->mtxComponentFactory); 471 485 if (RT_SUCCESS(rc)) 472 486 { 473 487 #ifdef SUPDRV_USE_MUTEX_FOR_LDR 474 rc = RTSemMutexCreate(&pDevExt->mtx Ldr);488 rc = RTSemMutexCreate(&pDevExt->mtxGip); 475 489 #else 476 rc = RTSemFastMutexCreate(&pDevExt->mtx Ldr);490 rc = RTSemFastMutexCreate(&pDevExt->mtxGip); 477 491 #endif 478 492 if (RT_SUCCESS(rc)) 479 493 { 480 rc = RTSemFastMutexCreate(&pDevExt->mtxComponentFactory);494 rc = supdrvGipCreate(pDevExt); 481 495 if (RT_SUCCESS(rc)) 482 496 { 483 #ifdef SUPDRV_USE_MUTEX_FOR_LDR 484 rc = RTSemMutexCreate(&pDevExt->mtxGip); 485 #else 486 rc = RTSemFastMutexCreate(&pDevExt->mtxGip); 487 #endif 497 rc = supdrvTracerInit(pDevExt); 488 498 if (RT_SUCCESS(rc)) 489 499 { 490 rc = supdrvGipCreate(pDevExt); 491 if (RT_SUCCESS(rc)) 492 { 493 rc = supdrvTracerInit(pDevExt); 494 if (RT_SUCCESS(rc)) 495 { 496 pDevExt->pLdrInitImage = NULL; 497 pDevExt->hLdrInitThread = NIL_RTNATIVETHREAD; 498 pDevExt->u32Cookie = BIRD; /** @todo make this random? */ 499 pDevExt->cbSession = (uint32_t)cbSession; 500 501 /* 502 * Fixup the absolute symbols. 503 * 504 * Because of the table indexing assumptions we'll have a little #ifdef orgy 505 * here rather than distributing this to OS specific files. At least for now. 506 */ 500 pDevExt->pLdrInitImage = NULL; 501 pDevExt->hLdrInitThread = NIL_RTNATIVETHREAD; 502 pDevExt->u32Cookie = BIRD; /** @todo make this random? */ 503 pDevExt->cbSession = (uint32_t)cbSession; 504 505 /* 506 * Fixup the absolute symbols. 507 * 508 * Because of the table indexing assumptions we'll have a little #ifdef orgy 509 * here rather than distributing this to OS specific files. At least for now. 510 */ 507 511 #ifdef RT_OS_DARWIN 508 512 # if ARCH_BITS == 32 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 513 if (SUPR0GetPagingMode() >= SUPPAGINGMODE_AMD64) 514 { 515 g_aFunctions[0].pfn = (void *)1; /* SUPR0AbsIs64bit */ 516 g_aFunctions[1].pfn = (void *)0x80; /* SUPR0Abs64bitKernelCS - KERNEL64_CS, seg.h */ 517 g_aFunctions[2].pfn = (void *)0x88; /* SUPR0Abs64bitKernelSS - KERNEL64_SS, seg.h */ 518 g_aFunctions[3].pfn = (void *)0x88; /* SUPR0Abs64bitKernelDS - KERNEL64_SS, seg.h */ 519 } 520 else 521 g_aFunctions[0].pfn = g_aFunctions[1].pfn = g_aFunctions[2].pfn = g_aFunctions[4].pfn = (void *)0; 522 g_aFunctions[4].pfn = (void *)0x08; /* SUPR0AbsKernelCS - KERNEL_CS, seg.h */ 523 g_aFunctions[5].pfn = (void *)0x10; /* SUPR0AbsKernelSS - KERNEL_DS, seg.h */ 524 g_aFunctions[6].pfn = (void *)0x10; /* SUPR0AbsKernelDS - KERNEL_DS, seg.h */ 525 g_aFunctions[7].pfn = (void *)0x10; /* SUPR0AbsKernelES - KERNEL_DS, seg.h */ 526 g_aFunctions[8].pfn = (void *)0x10; /* SUPR0AbsKernelFS - KERNEL_DS, seg.h */ 527 g_aFunctions[9].pfn = (void *)0x48; /* SUPR0AbsKernelGS - CPU_DATA_GS, seg.h */ 524 528 # else /* 64-bit darwin: */ 525 526 527 528 529 530 531 532 533 534 529 g_aFunctions[0].pfn = (void *)1; /* SUPR0AbsIs64bit */ 530 g_aFunctions[1].pfn = (void *)(uintptr_t)ASMGetCS(); /* SUPR0Abs64bitKernelCS */ 531 g_aFunctions[2].pfn = (void *)(uintptr_t)ASMGetSS(); /* SUPR0Abs64bitKernelSS */ 532 g_aFunctions[3].pfn = (void *)0; /* SUPR0Abs64bitKernelDS */ 533 g_aFunctions[4].pfn = (void *)(uintptr_t)ASMGetCS(); /* SUPR0AbsKernelCS */ 534 g_aFunctions[5].pfn = (void *)(uintptr_t)ASMGetSS(); /* SUPR0AbsKernelSS */ 535 g_aFunctions[6].pfn = (void *)0; /* SUPR0AbsKernelDS */ 536 g_aFunctions[7].pfn = (void *)0; /* SUPR0AbsKernelES */ 537 g_aFunctions[8].pfn = (void *)0; /* SUPR0AbsKernelFS */ 538 g_aFunctions[9].pfn = (void *)0; /* SUPR0AbsKernelGS */ 535 539 536 540 # endif 537 541 #else /* !RT_OS_DARWIN */ 538 542 # if ARCH_BITS == 64 539 540 541 542 543 g_aFunctions[0].pfn = (void *)1; /* SUPR0AbsIs64bit */ 544 g_aFunctions[1].pfn = (void *)(uintptr_t)ASMGetCS(); /* SUPR0Abs64bitKernelCS */ 545 g_aFunctions[2].pfn = (void *)(uintptr_t)ASMGetSS(); /* SUPR0Abs64bitKernelSS */ 546 g_aFunctions[3].pfn = (void *)(uintptr_t)ASMGetDS(); /* SUPR0Abs64bitKernelDS */ 543 547 # else 544 548 g_aFunctions[0].pfn = g_aFunctions[1].pfn = g_aFunctions[2].pfn = g_aFunctions[4].pfn = (void *)0; 545 549 # endif 546 547 548 549 550 551 550 g_aFunctions[4].pfn = (void *)(uintptr_t)ASMGetCS(); /* SUPR0AbsKernelCS */ 551 g_aFunctions[5].pfn = (void *)(uintptr_t)ASMGetSS(); /* SUPR0AbsKernelSS */ 552 g_aFunctions[6].pfn = (void *)(uintptr_t)ASMGetDS(); /* SUPR0AbsKernelDS */ 553 g_aFunctions[7].pfn = (void *)(uintptr_t)ASMGetES(); /* SUPR0AbsKernelES */ 554 g_aFunctions[8].pfn = (void *)(uintptr_t)ASMGetFS(); /* SUPR0AbsKernelFS */ 555 g_aFunctions[9].pfn = (void *)(uintptr_t)ASMGetGS(); /* SUPR0AbsKernelGS */ 552 556 #endif /* !RT_OS_DARWIN */ 553 554 555 556 557 557 return VINF_SUCCESS; 558 } 559 560 supdrvGipDestroy(pDevExt); 561 } 558 562 559 563 #ifdef SUPDRV_USE_MUTEX_FOR_GIP 560 561 564 RTSemMutexDestroy(pDevExt->mtxGip); 565 pDevExt->mtxGip = NIL_RTSEMMUTEX; 562 566 #else 563 RTSemFastMutexDestroy(pDevExt->mtxGip); 564 pDevExt->mtxGip = NIL_RTSEMFASTMUTEX; 565 #endif 566 } 567 RTSemFastMutexDestroy(pDevExt->mtxComponentFactory); 568 pDevExt->mtxComponentFactory = NIL_RTSEMFASTMUTEX; 569 } 570 #ifdef SUPDRV_USE_MUTEX_FOR_LDR 571 RTSemMutexDestroy(pDevExt->mtxLdr); 572 pDevExt->mtxLdr = NIL_RTSEMMUTEX; 573 #else 574 RTSemFastMutexDestroy(pDevExt->mtxLdr); 575 pDevExt->mtxLdr = NIL_RTSEMFASTMUTEX; 567 RTSemFastMutexDestroy(pDevExt->mtxGip); 568 pDevExt->mtxGip = NIL_RTSEMFASTMUTEX; 576 569 #endif 577 570 } 578 RTSpinlockDestroy(pDevExt->hGipSpinlock); 579 pDevExt->hGipSpinlock = NIL_RTSPINLOCK; 580 } 581 RTSpinlockDestroy(pDevExt->Spinlock); 582 pDevExt->Spinlock = NIL_RTSPINLOCK; 583 } 571 RTSemFastMutexDestroy(pDevExt->mtxComponentFactory); 572 pDevExt->mtxComponentFactory = NIL_RTSEMFASTMUTEX; 573 } 574 #ifdef SUPDRV_USE_MUTEX_FOR_LDR 575 RTSemMutexDestroy(pDevExt->mtxLdr); 576 pDevExt->mtxLdr = NIL_RTSEMMUTEX; 577 #else 578 RTSemFastMutexDestroy(pDevExt->mtxLdr); 579 pDevExt->mtxLdr = NIL_RTSEMFASTMUTEX; 580 #endif 581 } 582 583 RTSpinlockDestroy(pDevExt->Spinlock); 584 pDevExt->Spinlock = NIL_RTSPINLOCK; 585 RTSpinlockDestroy(pDevExt->hGipSpinlock); 586 pDevExt->hGipSpinlock = NIL_RTSPINLOCK; 587 RTSpinlockDestroy(pDevExt->hSessionHashTabSpinlock); 588 pDevExt->hSessionHashTabSpinlock = NIL_RTSPINLOCK; 589 584 590 #ifdef SUPDRV_WITH_RELEASE_LOGGER 585 591 RTLogDestroy(RTLogRelSetDefaultInstance(NULL)); … … 622 628 RTSemFastMutexDestroy(pDevExt->mtxComponentFactory); 623 629 pDevExt->mtxComponentFactory = NIL_RTSEMFASTMUTEX; 630 RTSpinlockDestroy(pDevExt->hSessionHashTabSpinlock); 631 pDevExt->hSessionHashTabSpinlock = NIL_RTSPINLOCK; 624 632 625 633 /* … … 700 708 pSession->u32Cookie = BIRD_INV; 701 709 pSession->fUnrestricted = fUnrestricted; 710 /*pSession->fInHashTable = false; */ 702 711 pSession->cRefs = 1; 703 /*pSession->pLdrUsage = NULL; 704 pSession->pVM = NULL; 705 pSession->pUsage = NULL; 706 pSession->pGip = NULL; 707 pSession->fGipReferenced = false; 708 pSession->Bundle.cUsed = 0; */ 709 pSession->Uid = NIL_RTUID; 710 pSession->Gid = NIL_RTGID; 712 /*pSession->pCommonNextHash = NULL; 713 pSession->ppOsSessionPtr = NULL; */ 711 714 if (fUser) 712 715 { … … 719 722 pSession->R0Process = NIL_RTR0PROCESS; 720 723 } 724 /*pSession->pLdrUsage = NULL; 725 pSession->pVM = NULL; 726 pSession->pUsage = NULL; 727 pSession->pGip = NULL; 728 pSession->fGipReferenced = false; 729 pSession->Bundle.cUsed = 0; */ 730 pSession->Uid = NIL_RTUID; 731 pSession->Gid = NIL_RTGID; 721 732 /*pSession->uTracerData = 0;*/ 722 733 pSession->hTracerCaller = NIL_RTNATIVETHREAD; … … 746 757 747 758 /** 748 * Shared code for cleaning up a session (but not quite freeing it). 749 * 750 * This is primarily intended for MAC OS X where we have to clean up the memory 751 * stuff before the file handle is closed. 752 * 753 * @param pDevExt Device extension. 759 * Cleans up the session in the context of the process to which it belongs, the 760 * caller will free the session and the session spinlock. 761 * 762 * This should normally occur when the session is closed or as the process 763 * exits. Careful reference counting in the OS specfic code makes sure that 764 * there cannot be any races between process/handle cleanup callbacks and 765 * threads doing I/O control calls. 766 * 767 * @param pDevExt The device extension. 754 768 * @param pSession Session data. 755 * This data will be freed by this routine.756 769 */ 757 770 static void supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) … … 760 773 PSUPDRVBUNDLE pBundle; 761 774 LogFlow(("supdrvCleanupSession: pSession=%p\n", pSession)); 775 776 Assert(!pSession->fInHashTable); 777 Assert(!pSession->ppOsSessionPtr); 778 AssertReleaseMsg(pSession->R0Process == RTR0ProcHandleSelf() || pSession->R0Process == NIL_RTR0PROCESS, 779 ("R0Process=%p cur=%p; Process=%u curpid=%u\n", RTR0ProcHandleSelf(), RTProcSelf())); 762 780 763 781 /* … … 964 982 965 983 /** 966 * Shared code for cleaning up a session.984 * Common code for freeing a session when the reference count reaches zero. 967 985 * 968 986 * @param pDevExt Device extension. … … 970 988 * This data will be freed by this routine. 971 989 */ 972 static void supdrv CloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)990 static void supdrvDestroySession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) 973 991 { 974 992 VBOXDRV_SESSION_CLOSE(pSession); … … 978 996 */ 979 997 supdrvCleanupSession(pDevExt, pSession); 998 supdrvOSCleanupSession(pDevExt, pSession); 980 999 981 1000 /* … … 986 1005 pSession->pDevExt = NULL; 987 1006 RTMemFree(pSession); 988 LogFlow(("supdrvCloseSession: returns\n")); 1007 LogFlow(("supdrvDestroySession: returns\n")); 1008 } 1009 1010 1011 /** 1012 * Inserts the session into the global hash table. 1013 * 1014 * @retval VINF_SUCCESS on success. 1015 * @retval VERR_WRONG_ORDER if the session was already inserted (asserted). 1016 * @retval VERR_INVALID_PARAMETER if the session handle is invalid or a ring-0 1017 * session (asserted). 1018 * @retval VERR_DUPLICATE if there is already a session for that pid. 1019 * 1020 * @param pDevExt The device extension. 1021 * @param pSession The session. 1022 * @param ppOsSessionPtr Pointer to the OS session pointer, if any is 1023 * available and used. This will set to point to the 1024 * session while under the protection of the session 1025 * hash table spinlock. It will also be kept in 1026 * PSUPDRVSESSION::ppOsSessionPtr for lookup and 1027 * cleanup use. 1028 * @param pvUser Argument for supdrvOSSessionHashTabInserted. 1029 */ 1030 int VBOXCALL supdrvSessionHashTabInsert(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPDRVSESSION *ppOsSessionPtr, 1031 void *pvUser) 1032 { 1033 PSUPDRVSESSION pCur; 1034 unsigned iHash; 1035 1036 /* 1037 * Validate input. 1038 */ 1039 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER); 1040 AssertReturn(pSession->R0Process != NIL_RTR0PROCESS, VERR_INVALID_PARAMETER); 1041 1042 /* 1043 * Calculate the hash table index and acquire the spinlock. 1044 */ 1045 iHash = SUPDRV_SESSION_HASH(pSession->Process); 1046 1047 RTSpinlockAcquire(pDevExt->hSessionHashTabSpinlock); 1048 1049 /* 1050 * If there are a collisions, we need to carefully check if we got a 1051 * duplicate. There can only be one open session per process. 1052 */ 1053 pCur = pDevExt->apSessionHashTab[iHash]; 1054 if (pCur) 1055 { 1056 while (pCur && pCur->Process != pSession->Process) 1057 pCur = pCur->pCommonNextHash; 1058 1059 if (pCur) 1060 { 1061 RTSpinlockRelease(pDevExt->hSessionHashTabSpinlock); 1062 if (pCur == pSession) 1063 { 1064 Assert(pSession->fInHashTable); 1065 AssertFailed(); 1066 return VERR_WRONG_ORDER; 1067 } 1068 Assert(!pSession->fInHashTable); 1069 if (pCur->R0Process == pSession->R0Process) 1070 return VERR_RESOURCE_IN_USE; 1071 return VERR_DUPLICATE; 1072 } 1073 } 1074 Assert(!pSession->fInHashTable); 1075 Assert(!pSession->ppOsSessionPtr); 1076 1077 /* 1078 * Insert it, doing a callout to the OS specific code in case it has 1079 * anything it wishes to do while we're holding the spinlock. 1080 */ 1081 pSession->pCommonNextHash = pDevExt->apSessionHashTab[iHash]; 1082 pDevExt->apSessionHashTab[iHash] = pSession; 1083 pSession->fInHashTable = true; 1084 ASMAtomicIncS32(&pDevExt->cSessions); 1085 1086 pSession->ppOsSessionPtr = ppOsSessionPtr; 1087 if (ppOsSessionPtr) 1088 ASMAtomicWritePtr(ppOsSessionPtr, pSession); 1089 1090 supdrvOSSessionHashTabInserted(pDevExt, pSession, pvUser); 1091 1092 /* 1093 * Retain a reference for the pointer in the session table. 1094 */ 1095 ASMAtomicIncU32(&pSession->cRefs); 1096 1097 RTSpinlockRelease(pDevExt->hSessionHashTabSpinlock); 1098 return VINF_SUCCESS; 1099 } 1100 1101 1102 /** 1103 * Removes the session from the global hash table. 1104 * 1105 * @retval VINF_SUCCESS on success. 1106 * @retval VERR_NOT_FOUND if the session was already removed (asserted). 1107 * @retval VERR_INVALID_PARAMETER if the session handle is invalid or a ring-0 1108 * session (asserted). 1109 * 1110 * @param pDevExt The device extension. 1111 * @param pSession The session. The caller is expected to have a reference 1112 * to this so it won't croak on us when we release the hash 1113 * table reference. 1114 * @param pvUser OS specific context value for the 1115 * supdrvOSSessionHashTabInserted callback. 1116 */ 1117 int VBOXCALL supdrvSessionHashTabRemove(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 1118 { 1119 PSUPDRVSESSION pCur; 1120 unsigned iHash; 1121 int32_t cRefs; 1122 1123 /* 1124 * Validate input. 1125 */ 1126 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER); 1127 AssertReturn(pSession->R0Process != NIL_RTR0PROCESS, VERR_INVALID_PARAMETER); 1128 1129 /* 1130 * Calculate the hash table index and acquire the spinlock. 1131 */ 1132 iHash = SUPDRV_SESSION_HASH(pSession->Process); 1133 1134 RTSpinlockAcquire(pDevExt->hSessionHashTabSpinlock); 1135 1136 /* 1137 * Unlink it. 1138 */ 1139 pCur = pDevExt->apSessionHashTab[iHash]; 1140 if (pCur == pSession) 1141 pDevExt->apSessionHashTab[iHash] = pSession->pCommonNextHash; 1142 else 1143 { 1144 PSUPDRVSESSION pPrev = pCur; 1145 while (pCur && pCur != pSession) 1146 { 1147 pPrev = pCur; 1148 pCur = pCur->pCommonNextHash; 1149 } 1150 if (pCur) 1151 pPrev->pCommonNextHash = pCur->pCommonNextHash; 1152 else 1153 { 1154 Assert(!pSession->fInHashTable); 1155 RTSpinlockRelease(pDevExt->hSessionHashTabSpinlock); 1156 return VERR_NOT_FOUND; 1157 } 1158 } 1159 1160 pSession->pCommonNextHash = NULL; 1161 pSession->fInHashTable = false; 1162 1163 ASMAtomicDecU32(&pDevExt->cSessions); 1164 1165 /* 1166 * Clear OS specific session pointer if available and do the OS callback. 1167 */ 1168 if (pSession->ppOsSessionPtr) 1169 { 1170 ASMAtomicCmpXchgPtr(pSession->ppOsSessionPtr, NULL, pSession); 1171 pSession->ppOsSessionPtr = NULL; 1172 } 1173 1174 supdrvOSSessionHashTabRemoved(pDevExt, pSession, pvUser); 1175 1176 RTSpinlockRelease(pDevExt->hSessionHashTabSpinlock); 1177 1178 /* 1179 * Drop the reference the hash table had to the session. This shouldn't 1180 * be the last reference! 1181 */ 1182 cRefs = ASMAtomicDecU32(&pSession->cRefs); 1183 Assert(cRefs > 0 && cRefs < _1M); 1184 if (cRefs == 0) 1185 supdrvDestroySession(pDevExt, pSession); 1186 1187 return VINF_SUCCESS; 1188 } 1189 1190 1191 /** 1192 * Looks up the session for the current process in the global hash table or in 1193 * OS specific pointer. 1194 * 1195 * @returns Pointer to the session with a reference that the caller must 1196 * release. If no valid session was found, NULL is returned. 1197 * 1198 * @param pDevExt The device extension. 1199 * @param Process The process ID. 1200 * @param R0Process The ring-0 process handle. 1201 * @param ppOsSessionPtr The OS session pointer if available. If not NULL, 1202 * this is used instead of the hash table. For 1203 * additional safety it must then be equal to the 1204 * SUPDRVSESSION::ppOsSessionPtr member. 1205 * This can be NULL even if the OS has a session 1206 * pointer. 1207 */ 1208 PSUPDRVSESSION VBOXCALL supdrvSessionHashTabLookup(PSUPDRVDEVEXT pDevExt, RTPROCESS Process, RTR0PROCESS R0Process, 1209 PSUPDRVSESSION *ppOsSessionPtr) 1210 { 1211 PSUPDRVSESSION pCur; 1212 unsigned iHash; 1213 1214 /* 1215 * Validate input. 1216 */ 1217 AssertReturn(R0Process != NIL_RTR0PROCESS, NULL); 1218 1219 /* 1220 * Calculate the hash table index and acquire the spinlock. 1221 */ 1222 iHash = SUPDRV_SESSION_HASH(Process); 1223 1224 RTSpinlockAcquire(pDevExt->hSessionHashTabSpinlock); 1225 1226 /* 1227 * If an OS session pointer is provided, always use it. 1228 */ 1229 if (ppOsSessionPtr) 1230 { 1231 pCur = *ppOsSessionPtr; 1232 if ( pCur 1233 && ( pCur->ppOsSessionPtr != ppOsSessionPtr 1234 || pCur->Process != Process 1235 || pCur->R0Process != R0Process) ) 1236 pCur = NULL; 1237 } 1238 else 1239 { 1240 /* 1241 * Otherwise, do the hash table lookup. 1242 */ 1243 pCur = pDevExt->apSessionHashTab[iHash]; 1244 while ( pCur 1245 && ( pCur->Process != Process 1246 || pCur->R0Process != R0Process) ) 1247 pCur = pCur->pCommonNextHash; 1248 } 1249 1250 /* 1251 * Retain the session. 1252 */ 1253 if (pCur) 1254 { 1255 uint32_t cRefs = ASMAtomicIncU32(&pCur->cRefs); 1256 Assert(cRefs > 1 && cRefs < _1M); 1257 } 1258 1259 RTSpinlockRelease(pDevExt->hSessionHashTabSpinlock); 1260 1261 return pCur; 989 1262 } 990 1263 … … 1023 1296 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pSession)); 1024 1297 if (cRefs == 0) 1025 supdrv CloseSession(pSession->pDevExt, pSession);1298 supdrvDestroySession(pSession->pDevExt, pSession); 1026 1299 return cRefs; 1027 1300 } -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r49965 r51770 59 59 # define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap 60 60 # pragma warning(disable : 4163) 61 # include < ntddk.h>61 # include <iprt/nt/nt.h> 62 62 # pragma warning(default : 4163) 63 63 # undef _InterlockedExchange … … 70 70 # undef _interlockedbittestandreset64 71 71 # else 72 # include < ntddk.h>72 # include <iprt/nt/nt.h> 73 73 # endif 74 74 # include <memory.h> … … 177 177 */ 178 178 #define OSDBGPRINT(a) SUPR0Printf a 179 180 /** Debug printf macro shared with the ring-3 part. */ 181 #ifdef DEBUG_bird 182 # define SUP_DPRINTF(a) SUPR0Printf a 183 #else 184 # define SUP_DPRINTF(a) do { } while (0) 185 #endif 179 186 180 187 … … 435 442 /** Set if is an unrestricted session, clear if restricted. */ 436 443 bool fUnrestricted; 437 /* Reference counter. */ 444 445 /** Set if we're in the hash table, clear if not. Protected by the hash 446 * table spinlock. */ 447 bool fInHashTable; 448 /** Reference counter. */ 438 449 uint32_t volatile cRefs; 450 /** Pointer to the next session with the same hash (common hash table). 451 * Protected by the hash table spinlock. */ 452 PSUPDRVSESSION pCommonNextHash; 453 /** Pointer to the OS specific session pointer, if available and in use. 454 * This is atomically set and cleared as the session is inserted and removed 455 * from the hash table (protected by the session hash table spinlock). */ 456 PSUPDRVSESSION *ppOsSessionPtr; 457 /** The process (id) of the session. */ 458 RTPROCESS Process; 459 /** Which process this session is associated with. 460 * This is NIL_RTR0PROCESS for kernel sessions and valid for user ones. */ 461 RTR0PROCESS R0Process; 439 462 440 463 /** The VM associated with the session. */ … … 446 469 PSUPDRVLDRUSAGE volatile pLdrUsage; 447 470 448 /** Spinlock protecting the bundles and the GIP members. */ 471 /** Spinlock protecting the bundles, the GIP members and the 472 * fProcessCleanupDone flag. It continues to be valid until the last 473 * reference to the session is released. */ 449 474 RTSPINLOCK Spinlock; 450 475 /** The ring-3 mapping of the GIP (readonly). */ … … 461 486 /** The group id of the session. (Set by the OS part.) */ 462 487 RTGID Gid; 463 /** The process (id) of the session. */464 RTPROCESS Process;465 /** Which process this session is associated with.466 * This is NIL_RTR0PROCESS for kernel sessions and valid for user ones. */467 RTR0PROCESS R0Process;468 488 /** Per session tracer specfic data. */ 469 489 uintptr_t uTracerData; … … 498 518 PSUPDRVSESSION pNextHash; 499 519 # endif 520 # if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_HARDENING) 521 /** Pointer to the process protection structure for this session. */ 522 struct SUPDRVNTPROTECT *pNtProtect; 523 # endif 500 524 #endif /* !SUPDRV_AGNOSTIC */ 501 525 } SUPDRVSESSION; … … 613 637 RTLISTANCHOR aTrackerUmodHash[128]; 614 638 639 /** @name Session Handle Table. 640 * @{ */ 641 /** Spinlock protecting apSessionHashTab, cSessions, 642 * SUPDRVSESSION::ppOsSessionPtr, SUPDRVSESSION::pCommonNextHash, and possibly 643 * others depending on the OS. */ 644 RTSPINLOCK hSessionHashTabSpinlock; 645 /** Session hash table hash table. The size of this table must make sense in 646 * comparison to GVMM_MAX_HANDLES. */ 647 PSUPDRVSESSION apSessionHashTab[HC_ARCH_BITS == 64 ? 8191 : 127]; 648 /** The number of open sessions. */ 649 int32_t cSessions; 650 /** @} */ 651 615 652 /* 616 * Note! The non-agnostic bits must be a the very end of the structure!653 * Note! The non-agnostic bits must be at the very end of the structure! 617 654 */ 618 655 #ifndef SUPDRV_AGNOSTIC … … 626 663 } SUPDRVDEVEXT; 627 664 665 /** Calculates the index into g_apSessionHashTab.*/ 666 #define SUPDRV_SESSION_HASH(a_pid) ( (a_pid) % RT_ELEMENTS(((SUPDRVDEVEXT *)NULL)->apSessionHashTab) ) 667 628 668 629 669 RT_C_DECLS_BEGIN … … 632 672 * OS Specific Functions * 633 673 *******************************************************************************/ 674 /** 675 * Called to clean up the session structure before it's freed. 676 * 677 * @param pDevExt The device globals. 678 * @param pSession The session that's being cleaned up. 679 */ 680 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession); 681 682 /** 683 * Called to let the OS specfic code perform additional insertion work while 684 * still under the protection of the hash table spinlock. 685 * 686 * @param pDevExt The device globals. 687 * @param pSession The session that was inserted. 688 * @param pvUser User context specified to the insert call. 689 */ 690 void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser); 691 692 /** 693 * Called to let the OS specfic code perform additional removal work while still 694 * under the protection of the hash table spinlock. 695 * 696 * @param pDevExt The device globals. 697 * @param pSession The session that was removed. 698 * @param pvUser User context specified to the remove call. 699 */ 700 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser); 701 634 702 void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession); 635 703 bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc); … … 763 831 void VBOXCALL supdrvDeleteDevExt(PSUPDRVDEVEXT pDevExt); 764 832 int VBOXCALL supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted, PSUPDRVSESSION *ppSession); 833 int VBOXCALL supdrvSessionHashTabInsert(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPDRVSESSION *ppOsSessionPtr, void *pvUser); 834 int VBOXCALL supdrvSessionHashTabRemove(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser); 835 PSUPDRVSESSION VBOXCALL supdrvSessionHashTabLookup(PSUPDRVDEVEXT pDevExt, RTPROCESS Process, RTR0PROCESS R0Process, 836 PSUPDRVSESSION *ppOsSessionPtr); 765 837 uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession); 766 838 uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession); -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r49965 r51770 1542 1542 * Verify that the image file and parent directories are sane. 1543 1543 */ 1544 rc = supR3HardenedVerifyFile(szExecPath, RTHCUINTPTR_MAX, pErrInfo);1544 rc = supR3HardenedVerifyFile(szExecPath, RTHCUINTPTR_MAX, false /*fMaybe3rdParty*/, pErrInfo); 1545 1545 if (RT_FAILURE(rc)) 1546 1546 return rc; … … 1586 1586 */ 1587 1587 #ifdef VBOX_WITH_HARDENING 1588 int rc = supR3HardenedVerifyFile(pszFilename, RTHCUINTPTR_MAX, pErrInfo);1588 int rc = supR3HardenedVerifyFile(pszFilename, RTHCUINTPTR_MAX, true /*fMaybe3rdParty*/, pErrInfo); 1589 1589 if (RT_FAILURE(rc) && !RTErrInfoIsSet(pErrInfo)) 1590 1590 LogRel(("supR3HardenedVerifyFile: Verification of \"%s\" failed, rc=%Rrc\n", pszFilename, rc)); -
trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h
r49634 r51770 104 104 */ 105 105 #if defined(IN_SUP_HARDENED_R3) && defined(RT_OS_WINDOWS) 106 # define SUP_HARDENED_NEED_CRT_FUNCTIONS 107 DECLHIDDEN(int) suplibHardenedMemComp(void const *pvDst, const void *pvSrc, size_t cbToComp); 106 108 DECLHIDDEN(void *) suplibHardenedMemCopy(void *pvDst, const void *pvSrc, size_t cbToCopy); 109 DECLHIDDEN(void *) suplibHardenedMemSet(void *pvDst, int ch, size_t cbToSet); 107 110 DECLHIDDEN(char *) suplibHardenedStrCopy(char *pszDst, const char *pszSrc); 108 111 DECLHIDDEN(size_t) suplibHardenedStrLen(const char *psz); … … 112 115 DECLHIDDEN(int) suplibHardenedStrICmp(const char *psz1, const char *psz2); 113 116 #else 117 # undef SUP_HARDENED_NEED_CRT_FUNCTIONS 118 # define suplibHardenedMemComp memcmp 114 119 # define suplibHardenedMemCopy memcpy 120 # define suplibHardenedMemSet memset 115 121 # define suplibHardenedStrCopy strcpy 116 122 # define suplibHardenedStrLen strlen … … 120 126 # define suplibHardenedStrICmp stricmp 121 127 #endif 122 DECLNORETURN(void) suplibHardenedExit(RTEXITCODE rcExit); 128 DECLNORETURN(void) suplibHardenedExit(RTEXITCODE rcExit); 129 DECLHIDDEN(void) suplibHardenedPrintF(const char *pszFormat, ...); 130 DECLHIDDEN(void) suplibHardenedPrintFV(const char *pszFormat, va_list va); 131 123 132 /** @} */ 133 134 /** Debug output macro. */ 135 #ifdef DEBUG_bird 136 # ifdef IN_SUP_HARDENED_R3 137 # define SUP_DPRINTF(a) suplibHardenedPrintF a 138 # else 139 # define SUP_DPRINTF(a) RTLogPrintf a 140 # endif 141 #else 142 # define SUP_DPRINTF(a) do { } while (0) 143 #endif 124 144 125 145 … … 135 155 kSupIFT_Exe, 136 156 kSupIFT_Dll, 157 kSupIFT_Rc, 137 158 kSupIFT_Sys, 138 159 kSupIFT_Script, … … 276 297 typedef FNSUPR3PREINIT *PFNSUPR3PREINIT; 277 298 299 /** The current SUPR3HardenedMain state / location. */ 300 typedef enum SUPR3HARDENEDMAINSTATE 301 { 302 SUPR3HARDENEDMAINSTATE_NOT_YET_CALLED = 0, 303 SUPR3HARDENEDMAINSTATE_VERIFY_TRUST_READY, 304 SUPR3HARDENEDMAINSTATE_INIT_RUNTIME, 305 SUPR3HARDENEDMAINSTATE_GET_TRUSTED_MAIN, 306 SUPR3HARDENEDMAINSTATE_CALLED_TRUSTED_MAIN, 307 SUPR3HARDENEDMAINSTATE_END 308 } SUPR3HARDENEDMAINSTATE; 309 278 310 279 311 /******************************************************************************* … … 288 320 extern DECLHIDDEN(PSUPQUERYFUNCS) g_pSupFunctions; 289 321 #endif 322 extern DECLHIDDEN(SUPR3HARDENEDMAINSTATE) g_enmSupR3HardenedMainState; 290 323 291 324 … … 360 393 */ 361 394 DECLHIDDEN(int) supR3HardenedError(int rc, bool fFatal, const char *pszFormat, ...); 395 362 396 DECLHIDDEN(int) supR3HardenedVerifyAll(bool fFatal, bool fLeaveFilesOpen, const char *pszProgName); 363 397 DECLHIDDEN(int) supR3HardenedVerifyFixedDir(SUPINSTDIR enmDir, bool fFatal); 364 398 DECLHIDDEN(int) supR3HardenedVerifyFixedFile(const char *pszFilename, bool fFatal); 365 399 DECLHIDDEN(int) supR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, PRTERRINFO pErrInfo); 366 DECLHIDDEN(int) supR3HardenedVerifyFile(const char *pszFilename, RTHCUINTPTR hNativeFile, PRTERRINFO pErrInfo); 400 DECLHIDDEN(int) supR3HardenedVerifyFile(const char *pszFilename, RTHCUINTPTR hNativeFile, bool fMaybe3rdParty, 401 PRTERRINFO pErrInfo); 367 402 DECLHIDDEN(void) supR3HardenedGetPreInitData(PSUPPREINITDATA pPreInitData); 368 403 DECLHIDDEN(int) supR3HardenedRecvPreInitData(PCSUPPREINITDATA pPreInitData); 369 404 405 #ifdef RT_OS_WINDOWS 406 DECLHIDDEN(void) supR3HardenedWinInit(uint32_t fFlags); 407 DECLHIDDEN(void) supR3HardenedWinInitVersion(void); 408 DECLHIDDEN(void) supR3HardenedWinVerifyProcess(void); 409 DECLHIDDEN(void) supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(void); 410 DECLHIDDEN(bool) supR3HardenedWinIsReSpawnNeeded(int cArgs, char **papszArgs); 411 DECLHIDDEN(int) supR3HardenedWinReSpawn(void); 412 DECLHIDDEN(void *) supR3HardenedWinLoadLibrary(const char *pszName, bool fSystem32Only); 413 extern RTUTF16 g_wszSupLibHardenedExePath[1024]; 414 # ifdef RTPATH_MAX 415 extern char g_szSupLibHardenedExePath[RTPATH_MAX]; 416 # endif 417 #endif 370 418 371 419 SUPR3DECL(int) supR3PageLock(void *pvStart, size_t cPages, PSUPPAGE paPages); -
trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp
r49634 r51770 781 781 * Verify the image file. 782 782 */ 783 int rc = supR3HardenedVerifyFile(pszFilename, RTHCUINTPTR_MAX, pErrInfo);783 int rc = supR3HardenedVerifyFile(pszFilename, RTHCUINTPTR_MAX, true /*fMaybe3rdParty*/, pErrInfo); 784 784 if (RT_FAILURE(rc)) 785 785 { -
trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
r49500 r51770 5 5 6 6 /* 7 * Copyright (C) 2006-201 3Oracle Corporation7 * Copyright (C) 2006-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 121 121 *******************************************************************************/ 122 122 /** The pre-init data we pass on to SUPR3 (residing in VBoxRT). */ 123 static SUPPREINITDATA g_SupPreInitData;123 static SUPPREINITDATA g_SupPreInitData; 124 124 /** The program executable path. */ 125 static char g_szSupLibHardenedExePath[RTPATH_MAX]; 125 #ifndef RT_OS_WINDOWS 126 static 127 #endif 128 char g_szSupLibHardenedExePath[RTPATH_MAX]; 126 129 /** The program directory path. */ 127 static char g_szSupLibHardenedDirPath[RTPATH_MAX];130 static char g_szSupLibHardenedDirPath[RTPATH_MAX]; 128 131 129 132 /** The program name. */ 130 static const char *g_pszSupLibHardenedProgName;133 static const char *g_pszSupLibHardenedProgName; 131 134 132 135 #ifdef SUP_HARDENED_SUID 133 136 /** The real UID at startup. */ 134 static uid_t g_uid;137 static uid_t g_uid; 135 138 /** The real GID at startup. */ 136 static gid_t g_gid;139 static gid_t g_gid; 137 140 # ifdef RT_OS_LINUX 138 static uint32_t g_uCaps;141 static uint32_t g_uCaps; 139 142 # endif 140 143 #endif 144 145 /** The current SUPR3HardenedMain state / location. */ 146 SUPR3HARDENEDMAINSTATE g_enmSupR3HardenedMainState = SUPR3HARDENEDMAINSTATE_NOT_YET_CALLED; 141 147 142 148 … … 148 154 #endif 149 155 static PFNSUPTRUSTEDERROR supR3HardenedMainGetTrustedError(const char *pszProgName); 150 151 152 #ifdef RT_OS_WINDOWS153 /*154 * No CRT here, thank you.155 */156 157 /** memcpy */158 DECLHIDDEN(void *) suplibHardenedMemCopy(void *pvDst, const void *pvSrc, size_t cbToCopy)159 {160 size_t *puDst = (size_t *)pvDst;161 size_t const *puSrc = (size_t const *)pvSrc;162 while (cbToCopy >= sizeof(size_t))163 {164 *puDst++ = *puSrc++;165 cbToCopy -= sizeof(size_t);166 }167 168 uint8_t *pbDst = (uint8_t *)puDst;169 uint8_t const *pbSrc = (uint8_t const *)puSrc;170 while (cbToCopy > 0)171 {172 *pbDst++ = *pbSrc++;173 cbToCopy--;174 }175 176 return pvDst;177 }178 179 180 /** strcpy */181 DECLHIDDEN(char *) suplibHardenedStrCopy(char *pszDst, const char *pszSrc)182 {183 char *pszRet = pszDst;184 char ch;185 do186 {187 ch = *pszSrc++;188 *pszDst++ = ch;189 } while (ch);190 return pszRet;191 }192 193 194 /** strlen */195 DECLHIDDEN(size_t) suplibHardenedStrLen(const char *psz)196 {197 const char *pszStart = psz;198 while (*psz)199 psz++;200 return psz - pszStart;201 }202 203 204 /** strcat */205 DECLHIDDEN(char *) suplibHardenedStrCat(char *pszDst, const char *pszSrc)206 {207 char *pszRet = pszDst;208 while (*pszDst)209 pszDst++;210 suplibHardenedStrCopy(pszDst, pszSrc);211 return pszRet;212 }213 214 215 # ifdef RT_OS_WINDOWS216 /** stricmp */217 DECLHIDDEN(int) suplibHardenedStrICmp(const char *psz1, const char *psz2)218 {219 const char *pszOrg1 = psz1;220 const char *pszOrg2 = psz2;221 222 for (;;)223 {224 char ch1 = *psz1++;225 char ch2 = *psz1++;226 if (ch1 != ch2)227 {228 int rc = CompareStringA(LOCALE_USER_DEFAULT, NORM_IGNORECASE, pszOrg1, -1, pszOrg2, -1);229 # ifdef VBOX_STRICT230 if (rc == 0)231 __debugbreak();232 # endif233 return rc - 2;234 }235 if (ch1 == 0)236 return 0;237 }238 }239 # endif240 241 242 /** strcmp */243 DECLHIDDEN(int) suplibHardenedStrCmp(const char *psz1, const char *psz2)244 {245 for (;;)246 {247 char ch1 = *psz1++;248 char ch2 = *psz1++;249 if (ch1 != ch2)250 return ch1 < ch2 ? -1 : 1;251 if (ch1 == 0)252 return 0;253 }254 }255 256 257 /** strncmp */258 DECLHIDDEN(int) suplibHardenedStrNCmp(const char *psz1, const char *psz2, size_t cchMax)259 {260 while (cchMax-- > 0)261 {262 char ch1 = *psz1++;263 char ch2 = *psz1++;264 if (ch1 != ch2)265 return ch1 < ch2 ? -1 : 1;266 if (ch1 == 0)267 break;268 }269 return 0;270 }271 272 #endif /* RT_OS_WINDOWS */273 156 274 157 … … 423 306 do 424 307 { 425 unsigned iDigit = uValue & fDigitMask;308 *psz-- = pchDigits[uValue & fDigitMask]; 426 309 uValue >>= cShift; 427 428 *psz-- = uValue % 10;429 uValue /= 10;430 310 } while (uValue > 0); 431 311 432 312 if ((fFlags & RTSTR_F_SPECIAL) && uBase == 16) 433 313 { 434 *psz-- = 'x';314 *psz-- = !(fFlags & RTSTR_F_CAPITAL) ? 'x' : 'X'; 435 315 *psz-- = '0'; 436 316 } … … 442 322 443 323 /** 324 * Writes a wide character string to standard error. 325 * 326 * @param pwsz The string. 327 */ 328 static void suplibHardenedPrintWideStr(PCRTUTF16 pwsz) 329 { 330 for (;;) 331 { 332 RTUTF16 wc = *pwsz++; 333 if (!wc) 334 return; 335 if ( (wc < 0x7f && wc >= 0x20) 336 || wc == '\n' 337 || wc == '\r') 338 suplibHardenedPrintChr((char)wc); 339 else 340 { 341 suplibHardenedPrintStrN(RT_STR_TUPLE("\\x")); 342 suplibHardenedPrintHexOctal(wc, 16, 0); 343 } 344 } 345 } 346 347 #ifdef IPRT_NO_CRT 348 349 /** Buffer structure used by suplibHardenedOutput. */ 350 struct SUPLIBHARDENEDOUTPUTBUF 351 { 352 size_t off; 353 char szBuf[2048]; 354 }; 355 356 /** Callback for RTStrFormatV, see FNRTSTROUTPUT. */ 357 static DECLCALLBACK(size_t) suplibHardenedOutput(void *pvArg, const char *pachChars, size_t cbChars) 358 { 359 SUPLIBHARDENEDOUTPUTBUF *pBuf = (SUPLIBHARDENEDOUTPUTBUF *)pvArg; 360 size_t cbTodo = cbChars; 361 for (;;) 362 { 363 size_t cbSpace = sizeof(pBuf->szBuf) - pBuf->off - 1; 364 365 /* Flush the buffer? */ 366 if ( cbSpace == 0 367 || (cbTodo == 0 && pBuf->off)) 368 { 369 suplibHardenedPrintStrN(pBuf->szBuf, pBuf->off); 370 # ifdef RT_OS_WINDOWS 371 OutputDebugString(pBuf->szBuf); 372 # endif 373 pBuf->off = 0; 374 cbSpace = sizeof(pBuf->szBuf) - 1; 375 } 376 377 /* Copy the string into the buffer. */ 378 if (cbTodo == 1) 379 { 380 pBuf->szBuf[pBuf->off++] = *pachChars; 381 break; 382 } 383 if (cbSpace >= cbTodo) 384 { 385 memcpy(&pBuf->szBuf[pBuf->off], pachChars, cbTodo); 386 pBuf->off += cbTodo; 387 break; 388 } 389 memcpy(&pBuf->szBuf[pBuf->off], pachChars, cbSpace); 390 pBuf->off += cbSpace; 391 cbTodo -= cbSpace; 392 } 393 pBuf->szBuf[pBuf->off] = '\0'; 394 395 return cbChars; 396 } 397 398 #endif /* IPRT_NO_CRT */ 399 400 /** 444 401 * Simple printf to standard error. 445 402 * … … 449 406 DECLHIDDEN(void) suplibHardenedPrintFV(const char *pszFormat, va_list va) 450 407 { 408 #ifdef IPRT_NO_CRT 409 /* 410 * Use buffered output here to avoid character mixing on the windows 411 * console and to enable us to use OutputDebugString. 412 */ 413 SUPLIBHARDENEDOUTPUTBUF Buf; 414 Buf.off = 0; 415 Buf.szBuf[0] = '\0'; 416 RTStrFormatV(suplibHardenedOutput, &Buf, NULL, NULL, pszFormat, va); 417 418 #else /* !IPRT_NO_CRT */ 451 419 /* 452 420 * Format loop. … … 544 512 545 513 case 's': 546 { 547 const char *pszStr = va_arg(va, const char *); 548 if (!RT_VALID_PTR(pszStr)) 549 pszStr = "<NULL>"; 550 suplibHardenedPrintStr(pszStr); 514 if (chArgSize == 'l') 515 { 516 PCRTUTF16 pwszStr = va_arg(va, PCRTUTF16 ); 517 if (RT_VALID_PTR(pwszStr)) 518 suplibHardenedPrintWideStr(pwszStr); 519 else 520 suplibHardenedPrintStr("<NULL>"); 521 } 522 else 523 { 524 const char *pszStr = va_arg(va, const char *); 525 if (!RT_VALID_PTR(pszStr)) 526 pszStr = "<NULL>"; 527 suplibHardenedPrintStr(pszStr); 528 } 551 529 break; 552 }553 530 554 531 case 'd': … … 617 594 } 618 595 596 case 'R': 597 if (pszFormat[0] == 'r' && pszFormat[1] == 'c') 598 { 599 int iValue = va_arg(va, int); 600 if (iValue < 0) 601 { 602 suplibHardenedPrintChr('-'); 603 iValue = -iValue; 604 } 605 suplibHardenedPrintDecimal(iValue); 606 pszFormat += 2; 607 break; 608 } 609 /* fall thru */ 619 610 620 611 /* … … 636 627 if (pszLast != pszFormat) 637 628 suplibHardenedPrintStrN(pszLast, pszFormat - pszLast); 629 #endif /* !IPRT_NO_CRT */ 638 630 } 639 631 … … 652 644 va_end(va); 653 645 } 654 655 646 656 647 … … 863 854 864 855 #elif defined(RT_OS_WINDOWS) 865 HMODULE hExe = GetModuleHandle(NULL); 866 if (!GetModuleFileName(hExe, &g_szSupLibHardenedExePath[0], sizeof(g_szSupLibHardenedExePath))) 867 supR3HardenedFatal("supR3HardenedExecDir: GetModuleFileName failed, rc=%d\n", GetLastError()); 856 int cbRet = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, 857 g_wszSupLibHardenedExePath, -1, 858 g_szSupLibHardenedExePath, sizeof(g_szSupLibHardenedExePath), 859 NULL /*pchDefChar*/, NULL /* pfUsedDefChar */); 860 if (!cbRet) 861 supR3HardenedFatal("supR3HardenedExecDir: WideCharToMultiByte failed, rc=%d\n", GetLastError()); 868 862 #else 869 863 # error needs porting. … … 956 950 break; 957 951 952 case kSupInitOp_Misc: 958 953 case kSupInitOp_IPRT: 959 954 case kSupInitOp_Integrity: … … 988 983 #endif 989 984 { 990 PFNSUPTRUSTEDERROR pfnTrustedError = supR3HardenedMainGetTrustedError(g_pszSupLibHardenedProgName); 991 if (pfnTrustedError) 992 pfnTrustedError(pszWhere, enmWhat, rc, pszMsgFmt, va); 985 static volatile bool s_fRecursive = false; /* Loader hooks may cause recursion. */ 986 if (!s_fRecursive) 987 { 988 s_fRecursive = true; 989 990 PFNSUPTRUSTEDERROR pfnTrustedError = supR3HardenedMainGetTrustedError(g_pszSupLibHardenedProgName); 991 if (pfnTrustedError) 992 pfnTrustedError(pszWhere, enmWhat, rc, pszMsgFmt, va); 993 994 s_fRecursive = false; 995 } 993 996 } 994 997 … … 1082 1085 supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, 1083 1086 "Kernel memory allocation/mapping failed"); 1087 case VERR_SUPDRV_HARDENING_EVIL_HANDLE: 1088 supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "VERR_SUPDRV_HARDENING_EVIL_HANDLE"); 1089 case VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0: 1090 supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0"); 1091 case VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1: 1092 supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1"); 1093 case VERR_SUPLIB_NT_PROCESS_UNTRUSTED_2: 1094 supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "VERR_SUPLIB_NT_PROCESS_UNTRUSTED_2"); 1084 1095 default: 1085 1096 supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, … … 1325 1336 */ 1326 1337 #if defined(RT_OS_WINDOWS) 1327 /** @todo consider using LOAD_WITH_ALTERED_SEARCH_PATH here! */ 1328 HMODULE hMod = LoadLibraryEx(szPath, NULL /*hFile*/, 0 /* dwFlags */); 1338 HMODULE hMod = (HMODULE)supR3HardenedWinLoadLibrary(szPath, false /*fSystem32Only*/); 1329 1339 if (!hMod) 1330 1340 supR3HardenedFatalMsg("supR3HardenedMainInitRuntime", kSupInitOp_IPRT, VERR_MODULE_NOT_FOUND, 1331 "LoadLibrary Ex(\"%s\",,)failed (rc=%d)",1341 "LoadLibrary \"%s\" failed (rc=%d)", 1332 1342 szPath, GetLastError()); 1333 1343 PFNRTR3INITEX pfnRTInitEx = (PFNRTR3INITEX)GetProcAddress(hMod, SUP_HARDENED_SYM("RTR3InitEx")); … … 1408 1418 */ 1409 1419 #if defined(RT_OS_WINDOWS) 1410 /** @todo consider using LOAD_WITH_ALTERED_SEARCH_PATH here! */ 1411 HMODULE hMod = LoadLibraryEx(szPath, NULL /*hFile*/, 0 /* dwFlags */); 1420 HMODULE hMod = (HMODULE)supR3HardenedWinLoadLibrary(szPath, false /*fSystem32Only*/); 1412 1421 if (!hMod) 1413 1422 return NULL; … … 1452 1461 */ 1453 1462 #if defined(RT_OS_WINDOWS) 1454 /** @todo consider using LOAD_WITH_ALTERED_SEARCH_PATH here! */ 1455 HMODULE hMod = LoadLibraryEx(szPath, NULL /*hFile*/, 0 /* dwFlags */); 1463 HMODULE hMod = (HMODULE)supR3HardenedWinLoadLibrary(szPath, false /*fSystem32Only*/); 1456 1464 if (!hMod) 1457 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: LoadLibrary Ex(\"%s\",,)failed, rc=%d\n",1465 supR3HardenedFatal("supR3HardenedMainGetTrustedMain: LoadLibrary \"%s\" failed, rc=%d\n", 1458 1466 szPath, GetLastError()); 1459 1467 FARPROC pfn = GetProcAddress(hMod, SUP_HARDENED_SYM("TrustedMain")); … … 1536 1544 1537 1545 /* 1538 * Validate the installation. 1539 */ 1546 * Validate the installation. On Windows we leave the files open so they 1547 * cannot be tampered with after they've been verified. We also check 1548 * install loader hooks and check the process integrity. 1549 */ 1550 #ifndef RT_OS_WINDOWS 1540 1551 supR3HardenedVerifyAll(true /* fFatal */, false /* fLeaveFilesOpen */, pszProgName); 1552 #else 1553 supR3HardenedWinInit(fFlags); 1554 supR3HardenedVerifyAll(true /* fFatal */, true /* fLeaveFilesOpen */, pszProgName); 1555 supR3HardenedWinVerifyProcess(); 1556 #endif 1557 1558 #ifdef RT_OS_WINDOWS 1559 /* 1560 * On Windows we'll respawn the process with a special vboxdrv arrangement 1561 * in place to monitor access to the process for its inception. 1562 */ 1563 if ( !(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV) 1564 && supR3HardenedWinIsReSpawnNeeded(argc, argv)) 1565 return supR3HardenedWinReSpawn(); 1566 #endif 1541 1567 1542 1568 /* … … 1545 1571 if (!(fFlags & SUPSECMAIN_FLAGS_DONT_OPEN_DEV)) 1546 1572 supR3HardenedMainOpenDevice(); 1573 #ifdef RT_OS_WINDOWS 1574 supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(); 1575 g_enmSupR3HardenedMainState = SUPR3HARDENEDMAINSTATE_VERIFY_TRUST_READY; 1576 #endif 1547 1577 1548 1578 /* … … 1568 1598 * call RTR3InitEx. 1569 1599 */ 1600 g_enmSupR3HardenedMainState = SUPR3HARDENEDMAINSTATE_INIT_RUNTIME; 1570 1601 supR3HardenedMainInitRuntime(fFlags); 1571 1602 … … 1574 1605 * and pass control to it. 1575 1606 */ 1607 g_enmSupR3HardenedMainState = SUPR3HARDENEDMAINSTATE_GET_TRUSTED_MAIN; 1576 1608 PFNSUPTRUSTEDMAIN pfnTrustedMain = supR3HardenedMainGetTrustedMain(pszProgName); 1609 g_enmSupR3HardenedMainState = SUPR3HARDENEDMAINSTATE_CALLED_TRUSTED_MAIN; 1577 1610 return pfnTrustedMain(argc, argv, envp); 1578 1611 } 1579 1612 1580 1581 #ifdef RT_OS_WINDOWS1582 1583 extern "C" int main(int argc, char **argv, char **envp);1584 1585 /**1586 * The executable entry point.1587 */1588 extern "C" void __stdcall suplibHardenedWindowsMain(void)1589 {1590 RTEXITCODE rcExit = RTEXITCODE_FAILURE;1591 1592 /*1593 * Convert the arguments to UTF-8.1594 */1595 int cArgs;1596 PWSTR *papwszArgs = CommandLineToArgvW(GetCommandLineW(), &cArgs); /** @todo fix me! */1597 if (papwszArgs)1598 {1599 char **papszArgs = (char **)HeapAlloc(GetProcessHeap(), 0 /* dwFlags*/, (cArgs + 1) * sizeof(const char **));1600 if (papszArgs)1601 {1602 int iArg;1603 for (iArg = 0; iArg < cArgs; iArg++)1604 {1605 int cbNeeded = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, papwszArgs[iArg], -1, NULL /*pszDst*/, 0 /*cbDst*/,1606 NULL /*pchDefChar*/, NULL /* pfUsedDefChar */);1607 if (!cbNeeded)1608 {1609 suplibHardenedPrintF("CommandLineToArgvW failed on argument %d: %u\n", iArg, GetLastError());1610 break;1611 }1612 1613 papszArgs[iArg] = (char *)HeapAlloc(GetProcessHeap(), 0 /*dwFlags*/, cbNeeded);1614 if (!papszArgs[iArg])1615 {1616 suplibHardenedPrintF("HeapAlloc failed");1617 break;1618 }1619 1620 int cbRet = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, papwszArgs[iArg], -1, papszArgs[iArg], cbNeeded,1621 NULL /*pchDefChar*/, NULL /* pfUsedDefChar */);1622 if (!cbRet)1623 {1624 suplibHardenedPrintF("CommandLineToArgvW failed on argument %d: %u\n", iArg, GetLastError());1625 break;1626 }1627 }1628 if (iArg == cArgs)1629 {1630 papszArgs[iArg] = NULL;1631 1632 /*1633 * Call the main function.1634 */1635 rcExit = (RTEXITCODE)main(cArgs, papszArgs, NULL);1636 }1637 }1638 else1639 suplibHardenedPrintF("HeapAlloc failed\n");1640 }1641 else1642 suplibHardenedPrintF("CommandLineToArgvW failed\n");1643 1644 /*1645 * Exit the process (never return).1646 */1647 for (;;)1648 ExitProcess(rcExit);1649 }1650 1651 #endif -
trunk/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
r49211 r51770 74 74 75 75 #include "SUPLibInternal.h" 76 #if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_HARDENING) 77 # define SUPHNTVI_NO_NT_STUFF 78 # include "win/SUPHardenedVerify-win.h" 79 #endif 76 80 77 81 … … 86 90 #endif 87 91 92 /** Compare table file names with externally supplied names. */ 93 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 94 # define SUP_COMP_FILENAME suplibHardenedStrICmp 95 #else 96 # define SUP_COMP_FILENAME suplibHardenedStrCmp 97 #endif 98 88 99 89 100 /******************************************************************************* … … 107 118 108 119 #ifdef VBOX_WITH_RAW_MODE 109 { kSupIFT_ Dll,kSupID_AppPrivArch, false, "VMMGC.gc" },110 { kSupIFT_ Dll,kSupID_AppPrivArch, false, "VBoxDDGC.gc" },111 { kSupIFT_ Dll,kSupID_AppPrivArch, false, "VBoxDD2GC.gc" },120 { kSupIFT_Rc, kSupID_AppPrivArch, false, "VMMGC.gc" }, 121 { kSupIFT_Rc, kSupID_AppPrivArch, false, "VBoxDDGC.gc" }, 122 { kSupIFT_Rc, kSupID_AppPrivArch, false, "VBoxDD2GC.gc" }, 112 123 #endif 113 124 … … 154 165 { kSupIFT_Exe, kSupID_AppBin, false, "VBoxSVC" SUPLIB_EXE_SUFF }, 155 166 #ifdef RT_OS_WINDOWS 156 { kSupIFT_Dll, kSupID_ AppPrivArchComp,false, "VBoxC" SUPLIB_DLL_SUFF },167 { kSupIFT_Dll, kSupID_SharedLib, false, "VBoxC" SUPLIB_DLL_SUFF }, 157 168 #else 158 169 { kSupIFT_Exe, kSupID_AppPrivArch, false, "VBoxXPCOMIPCD" SUPLIB_EXE_SUFF }, … … 347 358 FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, 348 359 NULL, 349 OPEN_ ALWAYS,360 OPEN_EXISTING, 350 361 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 351 362 NULL); … … 466 477 if (RT_SUCCESS(rc)) 467 478 { 468 #if defined(RT_OS_WINDOWS) 479 #if defined(RT_OS_WINDOWS) /** @todo Need to use WCHAR on windows! */ 469 480 HANDLE hFile = CreateFile(szPath, 470 481 GENERIC_READ, 471 482 FILE_SHARE_READ, 472 483 NULL, 473 OPEN_ ALWAYS,484 OPEN_EXISTING, 474 485 FILE_ATTRIBUTE_NORMAL, 475 486 NULL); 476 487 if (hFile != INVALID_HANDLE_VALUE) 477 488 { 478 /** @todo Check the type, and verify the signature (separate function so we can skip it). */ 489 # if defined(VBOX_WITH_HARDENING) && !defined(IN_SUP_R3_STATIC) /* Latter: Not in VBoxCpuReport and friends. */ 490 491 char szErr[1024]; 492 RTERRINFO ErrInfo; 493 RTErrInfoInit(&ErrInfo, szErr, sizeof(szErr)); 494 495 uint32_t fFlags = SUPHNTVI_F_REQUIRE_BUILD_CERT; 496 if (pFile->enmType == kSupIFT_Rc) 497 fFlags |= SUPHNTVI_F_RC_IMAGE; 498 499 rc = supHardenedWinVerifyImageByHandleNoName(hFile, fFlags, &ErrInfo); 500 if (RT_FAILURE(rc)) 501 { 502 rc = supR3HardenedError(rc, fFatal, "supR3HardenedVerifyFileInternal: '%s': Image verify error rc=%Rrc: %s\n", 503 szPath, rc, szErr); 504 CloseHandle(hFile); 505 } 506 else 507 #endif 479 508 { 480 509 /* it's valid. */ … … 491 520 if (!pFile->fOptional || err != ERROR_FILE_NOT_FOUND) 492 521 rc = supR3HardenedError(VERR_PATH_NOT_FOUND, fFatal, 493 "supR3HardenedVerifyFileInternal: Failed to open \"%s\": err=%d\n", 494 szPath, err); 522 "supR3HardenedVerifyFileInternal: Failed to open '%s': err=%d\n", szPath, err); 495 523 } 496 524 #else /* UNIXY */ … … 581 609 if (RT_FAILURE(rc)) 582 610 return rc; 583 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 584 if (suplibHardenedStrICmp(szName, pszFilename)) 585 #else 586 if (suplibHardenedStrCmp(szName, pszFilename)) 587 #endif 611 if (SUP_COMP_FILENAME(szName, pszFilename)) 588 612 { 589 613 /* … … 596 620 if ( GetFullPathName(szName, RT_ELEMENTS(szName2), &szName2[0], &pszIgnored) 597 621 && GetFullPathName(pszFilename, RT_ELEMENTS(szName), &szName[0], &pszIgnored)) 598 if (! suplibHardenedStrICmp(szName2, szName))622 if (!SUP_COMP_FILENAME(szName2, szName)) 599 623 rc = VINF_SUCCESS; 600 624 #else … … 603 627 if ( realpath(szName, szName2) != NULL 604 628 && realpath(pszFilename, szName) != NULL) 605 if (! suplibHardenedStrCmp(szName2, szName))629 if (!SUP_COMP_FILENAME(szName2, szName)) 606 630 rc = VINF_SUCCESS; 607 631 #endif … … 645 669 const char *pszName = supR3HardenedPathFilename(pszFilename); 646 670 for (unsigned iFile = 0; iFile < RT_ELEMENTS(g_aSupInstallFiles); iFile++) 647 if (! suplibHardenedStrCmp(pszName, g_aSupInstallFiles[iFile].pszFile))671 if (!SUP_COMP_FILENAME(pszName, g_aSupInstallFiles[iFile].pszFile)) 648 672 { 649 673 int rc = supR3HardenedVerifySameFile(iFile, pszFilename, fFatal); … … 904 928 */ 905 929 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 906 if ( RT_C_IS_ALPHA(pszSrc[0])930 if ( !RT_C_IS_ALPHA(pszSrc[0]) 907 931 || pszSrc[1] != ':' 908 932 || !RTPATH_IS_SLASH(pszSrc[2])) … … 1442 1466 * as we ended up with when verifying the path. 1443 1467 * RTHCUINTPTR_MAX means NIL here. 1468 * @param fMaybe3rdParty Set if the file is could be a supplied by a 1469 * third party. Different validation rules may 1470 * apply to 3rd party code on some platforms. 1444 1471 * @param pErrInfo Where to return extended error information. 1445 1472 * Optional. 1446 1473 */ 1447 DECLHIDDEN(int) supR3HardenedVerifyFile(const char *pszFilename, RTHCUINTPTR hNativeFile, PRTERRINFO pErrInfo) 1474 DECLHIDDEN(int) supR3HardenedVerifyFile(const char *pszFilename, RTHCUINTPTR hNativeFile, 1475 bool fMaybe3rdParty, PRTERRINFO pErrInfo) 1448 1476 { 1449 1477 /* … … 1477 1505 1478 1506 /* 1479 * Verify the file .1507 * Verify the file handle against the last component, if specified. 1480 1508 */ 1481 1509 if (hNativeFile != RTHCUINTPTR_MAX) 1482 return supR3HardenedVerifySameFsObject(hNativeFile, &FsObjState, Info.szPath, pErrInfo); 1510 { 1511 rc = supR3HardenedVerifySameFsObject(hNativeFile, &FsObjState, Info.szPath, pErrInfo); 1512 if (RT_FAILURE(rc)) 1513 return rc; 1514 } 1515 1516 #ifdef RT_OS_WINDOWS 1517 /* 1518 * The files shall be signed on windows, verify that. 1519 */ 1520 HANDLE hVerify; 1521 if (hNativeFile == RTHCUINTPTR_MAX) 1522 hVerify = CreateFile(pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 1523 else if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hNativeFile, GetCurrentProcess(), &hVerify, 1524 GENERIC_READ, false /*bInheritHandle*/, 0 /*dwOptions*/)) 1525 hVerify = INVALID_HANDLE_VALUE; 1526 if (hVerify != INVALID_HANDLE_VALUE) 1527 { 1528 uint32_t fFlags = SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING; 1529 if (!fMaybe3rdParty) 1530 fFlags = SUPHNTVI_F_REQUIRE_BUILD_CERT; 1531 const char *pszSuffix = RTPathSuffix(pszFilename); 1532 if ( pszSuffix 1533 && pszSuffix[0] == '.' 1534 && ( RT_C_TO_LOWER(pszSuffix[1]) == 'r' 1535 || RT_C_TO_LOWER(pszSuffix[1]) == 'g') 1536 && RT_C_TO_LOWER(pszSuffix[2]) == 'c' 1537 && pszSuffix[3] == '\0' ) 1538 fFlags |= SUPHNTVI_F_RC_IMAGE; 1539 # ifndef IN_SUP_R3_STATIC /* Not in VBoxCpuReport and friends. */ 1540 rc = supHardenedWinVerifyImageByHandleNoName(hVerify, fFlags, pErrInfo); 1541 # endif 1542 CloseHandle(hVerify); 1543 } 1544 else 1545 rc = RTErrInfoSetF(pErrInfo, RTErrConvertFromWin32(GetLastError()), 1546 "Error %u trying to open (or duplicate handle for) '%s'", GetLastError(), pszFilename); 1547 if (RT_FAILURE(rc)) 1548 return rc; 1549 #endif 1550 1483 1551 return VINF_SUCCESS; 1484 1552 } -
trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
r51769 r51770 782 782 783 783 784 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) 785 { 786 NOREF(pDevExt); 787 NOREF(pSession); 788 } 789 790 791 void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 792 { 793 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 794 } 795 796 797 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 798 { 799 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 800 } 801 802 784 803 /** 785 804 * Initializes any OS specific object creator fields. -
trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
r49718 r51770 496 496 497 497 498 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) 499 { 500 NOREF(pDevExt); 501 NOREF(pSession); 502 } 503 504 505 void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 506 { 507 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 508 } 509 510 511 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 512 { 513 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 514 } 515 516 498 517 void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession) 499 518 { -
trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
r50008 r51770 809 809 810 810 811 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) 812 { 813 NOREF(pDevExt); 814 NOREF(pSession); 815 } 816 817 818 void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 819 { 820 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 821 } 822 823 824 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 825 { 826 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 827 } 828 829 811 830 /** 812 831 * Initializes any OS specific object creator fields. -
trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
r49634 r51770 364 364 365 365 366 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) 367 { 368 NOREF(pDevExt); 369 NOREF(pSession); 370 } 371 372 373 void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 374 { 375 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 376 } 377 378 379 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 380 { 381 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 382 } 383 384 366 385 void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession) 367 386 { -
trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
r50664 r51770 903 903 904 904 905 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) 906 { 907 NOREF(pDevExt); 908 NOREF(pSession); 909 } 910 911 912 void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 913 { 914 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 915 } 916 917 918 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 919 { 920 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 921 } 922 923 905 924 /** 906 925 * Initializes any OS specific object creator fields. -
trunk/src/VBox/HostDrivers/Support/testcase/Makefile.kmk
r43386 r51770 5 5 6 6 # 7 # Copyright (C) 2006-201 2Oracle Corporation7 # Copyright (C) 2006-2014 Oracle Corporation 8 8 # 9 9 # This file is part of VirtualBox Open Source Edition (OSE), as -
trunk/src/VBox/HostDrivers/Support/testcase/tstNtQueryStuff.cpp
r48952 r51770 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 29 29 * Header Files * 30 30 *******************************************************************************/ 31 #include <ntstatus.h> 32 #define WIN32_NO_STATUS 33 #include <Windows.h> 34 #include <winternl.h> 35 36 typedef enum 37 { 38 MemoryBasicInformation = 0, 39 MemoryWorkingSetList, 40 MemorySectionName, 41 MemoryBasicVlmInformation 42 } MEMORY_INFORMATION_CLASS; 43 44 typedef struct 45 { 46 UNICODE_STRING SectionFileName; 47 WCHAR NameBuffer[ANYSIZE_ARRAY]; 48 } MEMORY_SECTION_NAME; 49 50 extern "C" 51 NTSYSAPI NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE hProcess, 52 IN LPCVOID pvWhere, 53 IN MEMORY_INFORMATION_CLASS MemoryInfo, 54 OUT PVOID pvBuf, 55 IN SIZE_T cbBuf, 56 OUT PSIZE_T pcbReturned OPTIONAL); 57 58 #define ProcessDebugPort ((PROCESSINFOCLASS)7 ) 59 #define ProcessHandleCount ((PROCESSINFOCLASS)20) 60 #define ProcessWow64Information ((PROCESSINFOCLASS)26) 61 #define ProcessImageFileName ((PROCESSINFOCLASS)27) 62 #define ProcessDebugObjectHandle ((PROCESSINFOCLASS)30) 63 #define ProcessExecuteFlags ((PROCESSINFOCLASS)34) 64 #define ProcessImageFileNameWin32 ((PROCESSINFOCLASS)43) 65 #define ProcessImageFileMapping ((PROCESSINFOCLASS)44) 66 67 31 #include <iprt/nt/nt-and-windows.h> 68 32 #include <iprt/test.h> 69 33 #include <iprt/string.h> … … 304 268 if (NT_SUCCESS(rcNt)) 305 269 RTTestIPrintf(RTTESTLVL_ALWAYS, "BasicInfo:\n" 306 " UniqueProcessId = %#x (%6d)\n" 270 " UniqueProcessId = %#x (%6d)\n" 271 " InheritedFromUniqueProcessId = %#x (%6d)\n" 272 " ExitStatus = %#x\n" 307 273 " PebBaseAddress = %p\n" 308 " Reserved1 = %p ExitStatus?\n" 309 " Reserved2a = %p AffinityMask?\n" 310 " Reserved2b = %p (%6d) BasePriority?\n" 311 " Reserved3 = %p (%6d) InheritedFromUniqueProcessId?\n" 274 " AffinityMask = %#zx\n" 275 " BasePriority = %#zx\n" 312 276 , 313 277 BasicInfo.UniqueProcessId, BasicInfo.UniqueProcessId, 278 BasicInfo.InheritedFromUniqueProcessId, BasicInfo.InheritedFromUniqueProcessId, 279 BasicInfo.ExitStatus, 314 280 BasicInfo.PebBaseAddress, 315 BasicInfo.Reserved1, 316 BasicInfo.Reserved2[0], 317 BasicInfo.Reserved2[1], BasicInfo.Reserved2[1], 318 BasicInfo.Reserved3, BasicInfo.Reserved3 281 BasicInfo.AffinityMask, 282 BasicInfo.BasePriority 319 283 ); 320 321 284 322 285 /* Debugger present? */ … … 435 398 436 399 437 int main( )400 int main(int argc, char **argv) 438 401 { 439 402 RTEXITCODE rcExit = RTTestInitAndCreate("tstNtQueryStuff", &g_hTest); … … 443 406 444 407 g_hProcess = GetCurrentProcess(); 445 446 //tstQueryVirtualMemory(); 408 if (argc >= 2 && argv[1][0] != '-') 409 { 410 const char *pszPid = argv[1]; 411 uint32_t idPid = RTStrToInt32(pszPid); 412 413 uint32_t fAccess = PROCESS_QUERY_INFORMATION; 414 if (argc >= 3) 415 fAccess = RTStrToInt32(argv[2]); 416 417 g_hProcess = OpenProcess(fAccess, FALSE, idPid); 418 if (g_hProcess == NULL) 419 { 420 RTTestIFailed("Error %u opening process %u (%s)\n", GetLastError(), idPid, pszPid); 421 return RTTestSummaryAndDestroy(g_hTest); 422 } 423 } 424 425 tstQueryVirtualMemory(); 447 426 tstQueryInformationProcess(); 448 427 449 450 428 return RTTestSummaryAndDestroy(g_hTest); 451 429 } -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r51744 r51770 28 28 * Header Files * 29 29 *******************************************************************************/ 30 #define IPRT_NT_MAP_TO_ZW 30 31 #define LOG_GROUP LOG_GROUP_SUP_DRV 31 32 #include "../SUPDrvInternal.h" … … 34 35 35 36 #include <iprt/assert.h> 37 #include <iprt/avl.h> 38 #include <iprt/ctype.h> 36 39 #include <iprt/initterm.h> 37 40 #include <iprt/mem.h> 38 41 #include <iprt/process.h> 39 42 #include <iprt/power.h> 43 #include <iprt/spinlock.h> 40 44 #include <iprt/string.h> 41 45 #include <VBox/log.h> 46 #include <VBox/err.h> 42 47 43 48 #include <iprt/asm-amd64-x86.h> 49 50 #ifdef VBOX_WITH_HARDENING 51 # include "SUPHardenedVerify-win.h" 52 #endif 44 53 45 54 … … 66 75 #define DEVICE_NAME_DOS_USR L"\\DosDevices\\VBoxDrvU" 67 76 77 #ifdef VBOX_WITH_HARDENING 78 /** Win32 device name for hardened stub access. */ 79 # define DEVICE_NAME_STUB "\\\\.\\VBoxDrvStub" 80 /** NT device name for hardened stub access. */ 81 # define DEVICE_NAME_NT_STUB L"\\Device\\VBoxDrvStub" 82 ///** Win Symlink name for hardened stub access. */ 83 //# define DEVICE_NAME_DOS_STUB L"\\DosDevices\\VBoxDrvStub" 84 85 86 /** Macro for checking for deflecting calls to the stub device. */ 87 # define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) \ 88 do { if ((a_pDevObj) == g_pDevObjStub) supdrvNtCompleteRequest(STATUS_ACCESS_DENIED, a_pIrp); } while (0) 89 #else 90 # define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) do {} while (0) 91 #endif 92 68 93 /** Enables the fast I/O control code path. */ 69 94 #define VBOXDRV_WITH_FAST_IO … … 73 98 * Structures and Typedefs * 74 99 *******************************************************************************/ 75 #if 0 //def RT_ARCH_AMD6476 typedef struct SUPDRVEXECMEM77 {78 PMDL pMdl;79 void *pvMapping;80 void *pvAllocation;81 } SUPDRVEXECMEM, *PSUPDRVEXECMEM;82 #endif83 84 100 /** 85 101 * Device extension used by VBoxDrvU. … … 103 119 ? (PSUPDRVDEVEXT)pDevObj->DeviceExtension \ 104 120 : ((PSUPDRVDEVEXTUSR)pDevObj->DeviceExtension)->pMainDrvExt ) 121 122 #ifdef VBOX_WITH_HARDENING 123 124 /** 125 * Device extension used by VBoxDrvS. 126 */ 127 typedef struct SUPDRVDEVEXTSTUB 128 { 129 /** Common header. */ 130 SUPDRVDEVEXTUSR Common; 131 } SUPDRVDEVEXTSTUB; 132 /** Pointer to the VBoxDrvS device extension. */ 133 typedef SUPDRVDEVEXTSTUB *PSUPDRVDEVEXTSTUB; 134 /** Value of SUPDRVDEVEXTSTUB::Common.u32Cookie. */ 135 #define SUPDRVDEVEXTSTUB_COOKIE UINT32_C(0x90abcdef) 136 137 138 /** 139 * The kind of process we're protecting. 140 */ 141 typedef enum SUPDRVNTPROTECTKIND 142 { 143 kSupDrvNtProtectKind_Invalid = 0, 144 145 /** Stub process protection while performing process verification. 146 * Next: StubSpawning (or free) */ 147 kSupDrvNtProtectKind_StubUnverified, 148 /** Stub process protection before it creates the VM process. 149 * Next: StubParent, StubDead. */ 150 kSupDrvNtProtectKind_StubSpawning, 151 /** Stub process protection while having a VM process as child. 152 * Next: StubDead */ 153 kSupDrvNtProtectKind_StubParent, 154 /** Dead stub process. */ 155 kSupDrvNtProtectKind_StubDead, 156 157 /** Potential VM process. 158 * Next: VmProcessConfirmed, VmProcessDead. */ 159 kSupDrvNtProtectKind_VmProcessUnconfirmed, 160 /** Confirmed VM process. 161 * Next: VmProcessDead. */ 162 kSupDrvNtProtectKind_VmProcessConfirmed, 163 /** Dead VM process. */ 164 kSupDrvNtProtectKind_VmProcessDead, 165 166 /** End of valid protection kinds. */ 167 kSupDrvNtProtectKind_End 168 } SUPDRVNTPROTECTKIND; 169 170 /** 171 * A NT process protection structure. 172 */ 173 typedef struct SUPDRVNTPROTECT 174 { 175 /** The AVL node core structure. The process ID is the pid. */ 176 AVLPVNODECORE AvlCore; 177 /** Magic value (SUPDRVNTPROTECT_MAGIC). */ 178 uint32_t volatile u32Magic; 179 /** Reference counter. */ 180 uint32_t volatile cRefs; 181 /** The kind of process we're protecting. */ 182 SUPDRVNTPROTECTKIND volatile enmProcessKind; 183 /** Vista, 7 & 8: Hack to allow more rights to the handle returned by 184 * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */ 185 bool fFirstProcessCreateHandle : 1; 186 /** Vista, 7 & 8: Hack to allow more rights to the handle returned by 187 * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */ 188 bool fFirstThreadCreateHandle : 1; 189 /** 8.1: Hack to allow more rights to the handle returned by 190 * NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */ 191 bool fCsrssFirstProcessCreateHandle : 1; 192 /** Vista, 7 & 8: Hack to allow more rights to the handle duplicated by CSR 193 * during process creation. Only applicable to VmProcessUnconfirmed. */ 194 bool fCsrssFirstProcessDuplicateHandle : 1; 195 /** 7,: Hack to allow the supid themes service duplicate handle privileges to 196 * our process. */ 197 bool fThemesFirstProcessCreateHandle : 1; 198 199 /** The parent PID for VM processes, otherwise NULL. */ 200 HANDLE hParentPid; 201 /** The PID of the CSRSS process associated with this process. */ 202 HANDLE hCsrssPid; 203 /** Pointer to the CSRSS process structure (referenced). */ 204 PEPROCESS pCsrssProcess; 205 /** State dependent data. */ 206 union 207 { 208 /** A stub process in the StubParent state will keep a reference to a child 209 * while it's in the VmProcessUnconfirmed state so that it can be cleaned up 210 * correctly if things doesn't work out. */ 211 struct SUPDRVNTPROTECT *pChild; 212 /** A process in the VmProcessUnconfirmed state will keep a weak 213 * reference to the parent's protection structure so it can clean up the pChild 214 * refernece the parent has to it. */ 215 struct SUPDRVNTPROTECT *pParent; 216 } u; 217 } SUPDRVNTPROTECT; 218 /** Pointer to a NT process protection record. */ 219 typedef SUPDRVNTPROTECT *PSUPDRVNTPROTECT; 220 /** The SUPDRVNTPROTECT::u32Magic value (Robert A. Heinlein). */ 221 # define SUPDRVNTPROTECT_MAGIC UINT32_C(0x19070707) 222 /** The SUPDRVNTPROTECT::u32Magic value of a dead structure. */ 223 # define SUPDRVNTPROTECT_MAGIC_DEAD UINT32_C(0x19880508) 224 225 /** Pointer to ObRegisterCallbacks. */ 226 typedef NTSTATUS (NTAPI *PFNOBREGISTERCALLBACKS)(POB_CALLBACK_REGISTRATION, PVOID *); 227 /** Pointer to ObUnregisterCallbacks. */ 228 typedef VOID (NTAPI *PFNOBUNREGISTERCALLBACKS)(PVOID); 229 /** Pointer to PsSetCreateProcessNotifyRoutineEx. */ 230 typedef NTSTATUS (NTAPI *PFNPSSETCREATEPROCESSNOTIFYROUTINEEX)(PCREATE_PROCESS_NOTIFY_ROUTINE_EX, BOOLEAN); 231 /** Pointer to PsReferenceProcessFilePointer. */ 232 typedef NTSTATUS (NTAPI *PFNPSREFERENCEPROCESSFILEPOINTER)(PEPROCESS, PFILE_OBJECT *); 233 /** Pointer to PsIsProtectedProcessLight. */ 234 typedef BOOLEAN (NTAPI *PFNPSISPROTECTEDPROCESSLIGHT)(PEPROCESS); 235 236 #endif /* VBOX_WITH_HARDENINIG */ 105 237 106 238 … … 123 255 static NTSTATUS _stdcall VBoxDrvNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp); 124 256 static NTSTATUS VBoxDrvNtErr2NtStatus(int rc); 257 #ifdef VBOX_WITH_HARDENING 258 static NTSTATUS supdrvNtProtectInit(void); 259 static void supdrvNtProtectTerm(void); 260 static int supdrvNtProtectCreate(PSUPDRVNTPROTECT *ppNtProtect, HANDLE hPid, 261 SUPDRVNTPROTECTKIND enmProcessKind, bool fLink); 262 static void supdrvNtProtectRelease(PSUPDRVNTPROTECT pNtProtect); 263 static PSUPDRVNTPROTECT supdrvNtProtectLookup(HANDLE hPid); 264 static int supdrvNtProtectFindAssociatedCsrss(PSUPDRVNTPROTECT pNtProtect); 265 static int supdrvNtProtectVerifyProcess(PSUPDRVNTPROTECT pNtProtect); 266 267 static bool supdrvNtIsDebuggerAttached(void); 268 #endif 125 269 126 270 … … 175 319 #endif /* VBOXDRV_WITH_FAST_IO */ 176 320 321 #ifdef VBOX_WITH_HARDENING 322 /** Pointer to the stub device instance. */ 323 static PDEVICE_OBJECT g_pDevObjStub = NULL; 324 /** Spinlock protecting g_NtProtectTree as well as the releasing of protection 325 * structures. */ 326 static RTSPINLOCK g_hNtProtectLock = NIL_RTSPINLOCK; 327 /** AVL tree of SUPDRVNTPROTECT structures. */ 328 static AVLPVTREE g_NtProtectTree = NULL; 329 /** Cookie returned by ObRegisterCallbacks for the callbacks. */ 330 static PVOID g_pvObCallbacksCookie = NULL; 331 /** Combined windows NT version number. See SUP_MAKE_NT_VER_COMBINED. */ 332 uint32_t g_uNtVerCombined = 0; 333 /** Pointer to ObRegisterCallbacks if available.. */ 334 static PFNOBREGISTERCALLBACKS g_pfnObRegisterCallbacks = NULL; 335 /** Pointer to ObUnregisterCallbacks if available.. */ 336 static PFNOBUNREGISTERCALLBACKS g_pfnObUnRegisterCallbacks = NULL; 337 /** Pointer to PsSetCreateProcessNotifyRoutineEx if available.. */ 338 static PFNPSSETCREATEPROCESSNOTIFYROUTINEEX g_pfnPsSetCreateProcessNotifyRoutineEx = NULL; 339 /** Pointer to PsReferenceProcessFilePointer if available. */ 340 static PFNPSREFERENCEPROCESSFILEPOINTER g_pfnPsReferenceProcessFilePointer = NULL; 341 /** Pointer to PsIsProtectedProcessLight. */ 342 static PFNPSISPROTECTEDPROCESSLIGHT g_pfnPsIsProtectedProcessLight = NULL; 343 344 # ifdef RT_ARCH_AMD64 345 extern "C" { 346 /** Pointer to KiServiceLinkage (used to fake missing ZwQueryVirtualMemory on 347 * XP64 / W2K3-64). */ 348 PFNRT g_pfnKiServiceLinkage = NULL; 349 /** Pointer to KiServiceInternal (used to fake missing ZwQueryVirtualMemory on 350 * XP64 / W2K3-64) */ 351 PFNRT g_pfnKiServiceInternal = NULL; 352 } 353 # endif 354 #endif 355 177 356 178 357 /** … … 192 371 if (NT_SUCCESS(rcNt)) 193 372 { 194 UNICODE_STRING DosName ;195 RtlInitUnicodeString(&DosName , DEVICE_NAME_DOS_SYS);196 rcNt = IoCreateSymbolicLink(&DosName , &DevName);373 UNICODE_STRING DosNameSys; 374 RtlInitUnicodeString(&DosNameSys, DEVICE_NAME_DOS_SYS); 375 rcNt = IoCreateSymbolicLink(&DosNameSys, &DevName); 197 376 if (NT_SUCCESS(rcNt)) 198 377 { … … 204 383 if (NT_SUCCESS(rcNt)) 205 384 { 206 UNICODE_STRING DosName ;207 RtlInitUnicodeString(&DosName , DEVICE_NAME_DOS_USR);208 rcNt = IoCreateSymbolicLink(&DosName , &DevName);385 UNICODE_STRING DosNameUsr; 386 RtlInitUnicodeString(&DosNameUsr, DEVICE_NAME_DOS_USR); 387 rcNt = IoCreateSymbolicLink(&DosNameUsr, &DevName); 209 388 if (NT_SUCCESS(rcNt)) 210 389 { … … 213 392 pDevExtUsr->u32Cookie = SUPDRVDEVEXTUSR_COOKIE; 214 393 215 /* Done. */ 216 return rcNt; 394 #ifdef VBOX_WITH_HARDENING 395 /* 396 * Hardened stub device. 397 */ 398 RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_STUB); 399 rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTSTUB), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjStub); 400 if (NT_SUCCESS(rcNt)) 401 { 402 //UNICODE_STRING DosNameStub; 403 //RtlInitUnicodeString(&DosNameStub, DEVICE_NAME_DOS_STUB); 404 //rcNt = IoCreateSymbolicLink(&DosNameStub, &DevName); 405 if (NT_SUCCESS(rcNt)) 406 { 407 PSUPDRVDEVEXTSTUB pDevExtStub = (PSUPDRVDEVEXTSTUB)g_pDevObjStub->DeviceExtension; 408 pDevExtStub->Common.pMainDrvExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension; 409 pDevExtStub->Common.u32Cookie = SUPDRVDEVEXTSTUB_COOKIE; 410 #endif 411 412 /* Done. */ 413 return rcNt; 414 #ifdef VBOX_WITH_HARDENING 415 } 416 417 /* Bail out. */ 418 IoDeleteDevice(g_pDevObjStub); 419 g_pDevObjUsr = NULL; 420 } 421 IoDeleteSymbolicLink(&DosNameUsr); 422 #endif 217 423 } 218 219 /* Bail out. */220 424 IoDeleteDevice(g_pDevObjUsr); 221 425 g_pDevObjUsr = NULL; 222 426 } 223 IoDeleteSymbolicLink(&DosName );427 IoDeleteSymbolicLink(&DosNameSys); 224 428 } 225 429 IoDeleteDevice(g_pDevObjSys); … … 241 445 rcNt = IoDeleteSymbolicLink(&DosName); 242 446 243 PSUPDRVDEVEXTUSR pDevExtUsr = (PSUPDRVDEVEXTUSR)g_pDevObjUsr->DeviceExtension; 244 pDevExtUsr->pMainDrvExt = NULL; 245 447 #ifdef VBOX_WITH_HARDENING 448 //RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS_STUB); 449 //rcNt = IoDeleteSymbolicLink(&DosName); 450 #endif 451 452 if (g_pDevObjUsr) 453 { 454 PSUPDRVDEVEXTUSR pDevExtUsr = (PSUPDRVDEVEXTUSR)g_pDevObjUsr->DeviceExtension; 455 pDevExtUsr->pMainDrvExt = NULL; 456 } 457 #ifdef VBOX_WITH_HARDENING 458 if (g_pDevObjStub) 459 { 460 PSUPDRVDEVEXTSTUB pDevExtStub = (PSUPDRVDEVEXTSTUB)g_pDevObjStub->DeviceExtension; 461 pDevExtStub->Common.pMainDrvExt = NULL; 462 } 463 #endif 464 465 #ifdef VBOX_WITH_HARDENING 466 IoDeleteDevice(g_pDevObjStub); 467 g_pDevObjStub = NULL; 468 #endif 246 469 IoDeleteDevice(g_pDevObjUsr); 247 470 g_pDevObjUsr = NULL; … … 273 496 274 497 /* 275 * Create device. 276 * (That means creating a device object and a symbolic link so the DOS 277 * subsystems (OS/2, win32, ++) can access the device.) 498 * Initialize the runtime (IPRT). 278 499 */ 279 NTSTATUS rcNt = vboxdrvNtCreateDevices(pDrvObj); 280 if (NT_SUCCESS(rcNt)) 281 { 282 int vrc = RTR0Init(0); 283 if (RT_SUCCESS(vrc)) 284 { 285 Log(("VBoxDrv::DriverEntry\n")); 286 500 NTSTATUS rcNt; 501 int vrc = RTR0Init(0); 502 if (RT_SUCCESS(vrc)) 503 { 504 Log(("VBoxDrv::DriverEntry\n")); 505 506 #ifdef VBOX_WITH_HARDENING 507 /* 508 * Initialize process protection. 509 */ 510 rcNt = supdrvNtProtectInit(); 511 if (NT_SUCCESS(rcNt)) 512 #endif 513 { 287 514 /* 288 * Initialize the device extension. 515 * Create device. 516 * (That means creating a device object and a symbolic link so the DOS 517 * subsystems (OS/2, win32, ++) can access the device.) 289 518 */ 290 PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension; 291 memset(pDevExt, 0, sizeof(*pDevExt)); 292 293 vrc = supdrvInitDevExt(pDevExt, sizeof(SUPDRVSESSION)); 294 if (!vrc) 519 rcNt = vboxdrvNtCreateDevices(pDrvObj); 520 if (NT_SUCCESS(rcNt)) 295 521 { 296 522 /* 297 * Setup the driver entry points in pDrvObj.523 * Initialize the device extension. 298 524 */ 299 pDrvObj->DriverUnload = VBoxDrvNtUnload; 300 pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxDrvNtCreate; 301 pDrvObj->MajorFunction[IRP_MJ_CLEANUP] = VBoxDrvNtCleanup; 302 pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxDrvNtClose; 303 pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxDrvNtDeviceControl; 304 pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxDrvNtInternalDeviceControl; 305 pDrvObj->MajorFunction[IRP_MJ_READ] = VBoxDrvNtNotSupportedStub; 306 pDrvObj->MajorFunction[IRP_MJ_WRITE] = VBoxDrvNtNotSupportedStub; 307 308 /* more? */ 525 PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension; 526 memset(pDevExt, 0, sizeof(*pDevExt)); 527 528 vrc = supdrvInitDevExt(pDevExt, sizeof(SUPDRVSESSION)); 529 if (!vrc) 530 { 531 /* 532 * Setup the driver entry points in pDrvObj. 533 */ 534 pDrvObj->DriverUnload = VBoxDrvNtUnload; 535 pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxDrvNtCreate; 536 pDrvObj->MajorFunction[IRP_MJ_CLEANUP] = VBoxDrvNtCleanup; 537 pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxDrvNtClose; 538 pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxDrvNtDeviceControl; 539 pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxDrvNtInternalDeviceControl; 540 pDrvObj->MajorFunction[IRP_MJ_READ] = VBoxDrvNtNotSupportedStub; 541 pDrvObj->MajorFunction[IRP_MJ_WRITE] = VBoxDrvNtNotSupportedStub; 309 542 310 543 #ifdef VBOXDRV_WITH_FAST_IO 311 /* Fast I/O to speed up guest execution roundtrips. */312 pDrvObj->FastIoDispatch = (PFAST_IO_DISPATCH)&g_VBoxDrvFastIoDispatch;544 /* Fast I/O to speed up guest execution roundtrips. */ 545 pDrvObj->FastIoDispatch = (PFAST_IO_DISPATCH)&g_VBoxDrvFastIoDispatch; 313 546 #endif 314 547 315 /* Register ourselves for power state changes. */ 316 UNICODE_STRING CallbackName; 317 OBJECT_ATTRIBUTES Attr; 318 319 RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState"); 320 InitializeObjectAttributes(&Attr, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL); 321 322 rcNt = ExCreateCallback(&pDevExt->pObjPowerCallback, &Attr, TRUE, TRUE); 323 if (rcNt == STATUS_SUCCESS) 324 pDevExt->hPowerCallback = ExRegisterCallback(pDevExt->pObjPowerCallback, VBoxPowerDispatchCallback, 325 g_pDevObjSys); 326 327 Log(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n")); 328 return STATUS_SUCCESS; 329 } 330 331 Log(("supdrvInitDevExit failed with vrc=%d!\n", vrc)); 332 rcNt = VBoxDrvNtErr2NtStatus(vrc); 333 334 RTR0Term(); 335 } 336 else 337 { 338 Log(("RTR0Init failed with vrc=%d!\n", vrc)); 339 rcNt = VBoxDrvNtErr2NtStatus(vrc); 340 } 341 342 vboxdrvNtDestroyDevices(); 548 /* 549 * Register ourselves for power state changes. We don't 550 * currently care if this fails. 551 */ 552 UNICODE_STRING CallbackName; 553 RtlInitUnicodeString(&CallbackName, L"\\Callback\\PowerState"); 554 555 OBJECT_ATTRIBUTES Attr; 556 InitializeObjectAttributes(&Attr, &CallbackName, OBJ_CASE_INSENSITIVE, NULL, NULL); 557 558 rcNt = ExCreateCallback(&pDevExt->pObjPowerCallback, &Attr, TRUE, TRUE); 559 if (rcNt == STATUS_SUCCESS) 560 pDevExt->hPowerCallback = ExRegisterCallback(pDevExt->pObjPowerCallback, 561 VBoxPowerDispatchCallback, 562 g_pDevObjSys); 563 564 /* 565 * Done! Returning success! 566 */ 567 Log(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n")); 568 return STATUS_SUCCESS; 569 } 570 571 Log(("supdrvInitDevExit failed with vrc=%d!\n", vrc)); 572 rcNt = VBoxDrvNtErr2NtStatus(vrc); 573 574 vboxdrvNtDestroyDevices(); 575 } 576 #ifdef VBOX_WITH_HARDENING 577 supdrvNtProtectTerm(); 578 #endif 579 } 580 RTR0Term(); 581 } 582 else 583 { 584 Log(("RTR0Init failed with vrc=%d!\n", vrc)); 585 rcNt = VBoxDrvNtErr2NtStatus(vrc); 343 586 } 344 587 if (NT_SUCCESS(rcNt)) … … 369 612 */ 370 613 supdrvDeleteDevExt(pDevExt); 614 #ifdef VBOX_WITH_HARDENING 615 supdrvNtProtectTerm(); 616 #endif 371 617 RTR0Term(); 372 618 vboxdrvNtDestroyDevices(); … … 377 623 378 624 /** 625 * For simplifying request completion into a simple return statement, extended 626 * version. 627 * 628 * @returns rcNt 629 * @param rcNt The status code. 630 * @param uInfo Extra info value. 631 * @param pIrp The IRP. 632 */ 633 DECLINLINE(NTSTATUS) supdrvNtCompleteRequestEx(NTSTATUS rcNt, ULONG_PTR uInfo, PIRP pIrp) 634 { 635 pIrp->IoStatus.Status = rcNt; 636 pIrp->IoStatus.Information = uInfo; 637 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 638 return rcNt; 639 } 640 641 642 /** 643 * For simplifying request completion into a simple return statement. 644 * 645 * @returns rcNt 646 * @param rcNt The status code. 647 * @param pIrp The IRP. 648 */ 649 DECLINLINE(NTSTATUS) supdrvNtCompleteRequest(NTSTATUS rcNt, PIRP pIrp) 650 { 651 return supdrvNtCompleteRequestEx(rcNt, 0 /*uInfo*/, pIrp); 652 } 653 654 655 /** 379 656 * Create (i.e. Open) file entry point. 380 657 * … … 385 662 { 386 663 Log(("VBoxDrvNtCreate: RequestorMode=%d\n", pIrp->RequestorMode)); 387 const bool fUnrestricted = pDevObj == g_pDevObjSys; 388 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); 664 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); 389 665 PFILE_OBJECT pFileObj = pStack->FileObject; 390 PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj);666 PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj); 391 667 392 668 /* … … 395 671 */ 396 672 if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE) 397 { 398 pIrp->IoStatus.Status = STATUS_NOT_A_DIRECTORY; 399 pIrp->IoStatus.Information = 0; 400 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 401 return STATUS_NOT_A_DIRECTORY; 402 } 673 return supdrvNtCompleteRequest(STATUS_NOT_A_DIRECTORY, pIrp); 403 674 404 675 /* 405 676 * Don't create a session for kernel clients, they'll close the handle 406 677 * immediately and work with the file object via 407 * VBoxDrvNtInternalDeviceControl. The first request will there be one408 * tocreate a session.678 * VBoxDrvNtInternalDeviceControl. The first request will be one to 679 * create a session. 409 680 */ 410 681 NTSTATUS rcNt; 411 682 if (pIrp->RequestorMode == KernelMode) 412 rcNt = STATUS_SUCCESS; 683 { 684 if (pDevObj == g_pDevObjSys) 685 return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp); 686 687 rcNt = STATUS_ACCESS_DENIED; 688 } 413 689 else 414 690 { 691 #if defined(VBOX_WITH_HARDENING) && !defined(VBOX_WITHOUT_DEBUGGER_CHECKS) 415 692 /* 416 * Call common code for the rest.693 * Make sure no debuggers are attached to non-user processes. 417 694 */ 418 pFileObj->FsContext = NULL; 419 PSUPDRVSESSION pSession; 420 int rc = supdrvCreateSession(pDevExt, true /*fUser*/, fUnrestricted, &pSession); 421 if (!rc) 422 pFileObj->FsContext = pSession; 423 rcNt = pIrp->IoStatus.Status = VBoxDrvNtErr2NtStatus(rc); 424 } 425 426 pIrp->IoStatus.Information = 0; 427 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 428 429 return rcNt; 695 if ( pDevObj != g_pDevObjUsr 696 && supdrvNtIsDebuggerAttached()) 697 { 698 LogRel(("vboxdrv: Process %p is being debugged, access to vboxdrv / vboxdrvu declined.\n", 699 PsGetProcessId(PsGetCurrentProcess()))); 700 rcNt = STATUS_TRUST_FAILURE; 701 } 702 else 703 #endif 704 { 705 int rc = VINF_SUCCESS; 706 707 #ifdef VBOX_WITH_HARDENING 708 /* 709 * Access to the stub device is only granted to processes which 710 * passes verification. 711 * 712 * Note! The stub device has no need for a SUPDRVSESSION structure, 713 * so the it uses the SUPDRVNTPROTECT directly instead. 714 */ 715 if (pDevObj == g_pDevObjStub) 716 { 717 PSUPDRVNTPROTECT pNtProtect = NULL; 718 rc = supdrvNtProtectCreate(&pNtProtect, PsGetProcessId(PsGetCurrentProcess()), 719 kSupDrvNtProtectKind_StubUnverified, true /*fLink*/); 720 if (RT_SUCCESS(rc)) 721 { 722 rc = supdrvNtProtectFindAssociatedCsrss(pNtProtect); 723 if (RT_SUCCESS(rc)) 724 rc = supdrvNtProtectVerifyProcess(pNtProtect); 725 if (RT_SUCCESS(rc)) 726 { 727 pFileObj->FsContext = pNtProtect; /* Keeps reference. */ 728 return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp); 729 } 730 731 supdrvNtProtectRelease(pNtProtect); 732 } 733 LogRel(("vboxdrv: Declined %p access to VBoxDrvStub: rc=%d\n", PsGetProcessId(PsGetCurrentProcess()), rc)); 734 } 735 /* 736 * Unrestricted access is only granted to a process in the 737 * VmProcessUnconfirmed state that checks out correctly and is 738 * allowed to transition to VmProcessConfirmed. Again, only one 739 * session per process. 740 */ 741 else if (pDevObj != g_pDevObjUsr) 742 { 743 PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(PsGetProcessId(PsGetCurrentProcess())); 744 if (pNtProtect) 745 { 746 if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed) 747 { 748 rc = supdrvNtProtectVerifyProcess(pNtProtect); 749 if (RT_SUCCESS(rc)) 750 { 751 /* Create a session. */ 752 PSUPDRVSESSION pSession; 753 rc = supdrvCreateSession(pDevExt, true /*fUser*/, pDevObj == g_pDevObjSys /*fUnrestricted*/, 754 &pSession); 755 if (RT_SUCCESS(rc)) 756 { 757 rc = supdrvSessionHashTabInsert(pDevExt, pSession, (PSUPDRVSESSION *)&pFileObj->FsContext, NULL); 758 supdrvSessionRelease(pSession); 759 if (RT_SUCCESS(rc)) 760 { 761 pSession->pNtProtect = pNtProtect; /* Keeps reference. */ 762 return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp); 763 } 764 } 765 766 /* No second attempt. */ 767 RTSpinlockAcquire(g_hNtProtectLock); 768 if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessConfirmed) 769 pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead; 770 RTSpinlockRelease(g_hNtProtectLock); 771 772 LogRel(("vboxdrv: supdrvCreateSession failed for process %p: rc=%d.\n", 773 PsGetProcessId(PsGetCurrentProcess()), rc)); 774 } 775 else 776 LogRel(("vboxdrv: Process %p failed process verification: rc=%d.\n", 777 PsGetProcessId(PsGetCurrentProcess()), rc)); 778 } 779 else 780 { 781 LogRel(("vboxdrv: %p is not a budding VM process (enmProcessKind=%d).\n", 782 PsGetProcessId(PsGetCurrentProcess()), pNtProtect->enmProcessKind)); 783 rc = VERR_ACCESS_DENIED; 784 } 785 supdrvNtProtectRelease(pNtProtect); 786 } 787 else 788 { 789 LogRel(("vboxdrv: %p is not a budding VM process.\n", PsGetProcessId(PsGetCurrentProcess()))); 790 rc = VERR_ACCESS_DENIED; 791 } 792 } 793 /* 794 * Call common code to create an unprivileged session. 795 */ 796 else 797 { 798 PSUPDRVSESSION pSession; 799 rc = supdrvCreateSession(pDevExt, true /*fUser*/, false /*fUnrestricted*/, &pSession); 800 if (RT_SUCCESS(rc)) 801 { 802 rc = supdrvSessionHashTabInsert(pDevExt, pSession, (PSUPDRVSESSION *)&pFileObj->FsContext, NULL); 803 supdrvSessionRelease(pSession); 804 if (RT_SUCCESS(rc)) 805 { 806 pFileObj->FsContext = pSession; /* Keeps reference. No race. */ 807 pSession->pNtProtect = NULL; 808 return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp); 809 } 810 } 811 } 812 813 #else /* !VBOX_WITH_HARDENING */ 814 /* 815 * Call common code to create a session. 816 */ 817 pFileObj->FsContext = NULL; 818 PSUPDRVSESSION pSession; 819 rc = supdrvCreateSession(pDevExt, true /*fUser*/, pDevObj == g_pDevObjSys /*fUnrestricted*/, &pSession); 820 if (RT_SUCCESS(rc)) 821 { 822 rc = supdrvSessionHashTabInsert(pDevExt, pSession, (PSUPDRVSESSION *)&pFileObj->FsContext, NULL); 823 supdrvSessionRelease(pSession); 824 if (RT_SUCCESS(rc)) 825 return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp); 826 827 } 828 #endif /* !VBOX_WITH_HARDENING */ 829 830 /* bail out */ 831 rcNt = VBoxDrvNtErr2NtStatus(rc); 832 } 833 } 834 835 Assert(!NT_SUCCESS(rcNt)); 836 pFileObj->FsContext = NULL; 837 return supdrvNtCompleteRequest(rcNt, pIrp); /* Note. the IoStatus is completely ignored on error. */ 430 838 } 431 839 … … 442 850 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); 443 851 PFILE_OBJECT pFileObj = pStack->FileObject; 444 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFileObj->FsContext; 445 446 Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession)); 447 if (pSession) 448 { 449 supdrvSessionRelease(pSession); 450 pFileObj->FsContext = NULL; 451 } 452 453 pIrp->IoStatus.Information = 0; 454 pIrp->IoStatus.Status = STATUS_SUCCESS; 455 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 456 457 return STATUS_SUCCESS; 852 853 #ifdef VBOX_WITH_HARDENING 854 if (pDevObj == g_pDevObjStub) 855 { 856 PSUPDRVNTPROTECT pNtProtect = (PSUPDRVNTPROTECT)pFileObj->FsContext; 857 Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pNtProtect=%p\n", pDevExt, pFileObj, pNtProtect)); 858 if (pNtProtect) 859 { 860 supdrvNtProtectRelease(pNtProtect); 861 pFileObj->FsContext = NULL; 862 } 863 } 864 else 865 #endif 866 { 867 PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(), 868 (PSUPDRVSESSION *)&pFileObj->FsContext); 869 Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession)); 870 if (pSession) 871 { 872 supdrvSessionHashTabRemove(pDevExt, pSession, NULL); 873 supdrvSessionRelease(pSession); /* Drops the reference from supdrvSessionHashTabLookup. */ 874 } 875 } 876 877 return supdrvNtCompleteRequest(STATUS_SUCCESS, pIrp); 458 878 } 459 879 … … 470 890 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); 471 891 PFILE_OBJECT pFileObj = pStack->FileObject; 472 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFileObj->FsContext; 473 474 Log(("VBoxDrvNtClose: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession)); 475 if (pSession) 476 { 477 supdrvSessionRelease(pSession); 478 pFileObj->FsContext = NULL; 479 } 480 481 pIrp->IoStatus.Information = 0; 482 pIrp->IoStatus.Status = STATUS_SUCCESS; 483 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 484 485 return STATUS_SUCCESS; 892 893 #ifdef VBOX_WITH_HARDENING 894 if (pDevObj == g_pDevObjStub) 895 { 896 PSUPDRVNTPROTECT pNtProtect = (PSUPDRVNTPROTECT)pFileObj->FsContext; 897 Log(("VBoxDrvNtClose: pDevExt=%p pFileObj=%p pNtProtect=%p\n", pDevExt, pFileObj, pNtProtect)); 898 if (pNtProtect) 899 { 900 supdrvNtProtectRelease(pNtProtect); 901 pFileObj->FsContext = NULL; 902 } 903 } 904 else 905 #endif 906 { 907 PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(), 908 (PSUPDRVSESSION *)&pFileObj->FsContext); 909 Log(("VBoxDrvNtCleanup: pDevExt=%p pFileObj=%p pSession=%p\n", pDevExt, pFileObj, pSession)); 910 if (pSession) 911 { 912 supdrvSessionHashTabRemove(pDevExt, pSession, NULL); 913 supdrvSessionRelease(pSession); /* Drops the reference from supdrvSessionHashTabLookup. */ 914 } 915 } 916 917 return supdrvNtCompleteRequest(STATUS_SUCCESS, pIrp); 486 918 } 487 919 … … 510 942 { 511 943 PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj); 512 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFileObj->FsContext;513 944 514 945 /* 515 * Check the input a little bit .946 * Check the input a little bit and get a the session references. 516 947 */ 948 PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(), 949 (PSUPDRVSESSION *)&pFileObj->FsContext); 517 950 if (!pSession) 518 951 { 519 pIoStatus->Status = STATUS_ INVALID_PARAMETER;952 pIoStatus->Status = STATUS_TRUST_FAILURE; 520 953 pIoStatus->Information = 0; 521 954 return TRUE; 522 955 } 523 956 524 /* 525 * Deal with the 2-3 high-speed IOCtl that takes their arguments from 526 * the session and iCmd, and does not return anything. 527 */ 528 if ( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN 957 if (pSession->fUnrestricted) 958 { 959 #if defined(VBOX_WITH_HARDENING) && !defined(VBOX_WITHOUT_DEBUGGER_CHECKS) 960 if (supdrvNtIsDebuggerAttached()) 961 { 962 pIoStatus->Status = STATUS_TRUST_FAILURE; 963 pIoStatus->Information = 0; 964 supdrvSessionRelease(pSession); 965 return TRUE; 966 } 967 #endif 968 969 /* 970 * Deal with the 2-3 high-speed IOCtl that takes their arguments from 971 * the session and iCmd, and does not return anything. 972 */ 973 if ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN 529 974 || uCmd == SUP_IOCTL_FAST_DO_HM_RUN 530 975 || uCmd == SUP_IOCTL_FAST_DO_NOP) 531 && pSession->fUnrestricted == true) 532 { 533 int rc = supdrvIOCtlFast(uCmd, (unsigned)(uintptr_t)pvOutput /* VMCPU id */, pDevExt, pSession); 534 pIoStatus->Status = RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; 535 pIoStatus->Information = 0; /* Could be used to pass rc if we liked. */ 536 return TRUE; 976 { 977 int rc = supdrvIOCtlFast(uCmd, (unsigned)(uintptr_t)pvOutput/* VMCPU id */, pDevExt, pSession); 978 pIoStatus->Status = RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; 979 pIoStatus->Information = 0; /* Could be used to pass rc if we liked. */ 980 supdrvSessionRelease(pSession); 981 return TRUE; 982 } 537 983 } 538 984 … … 546 992 pDevExt, uCmd, pvInput, cbInput, pvOutput, cbOutput, pSession)); 547 993 548 # ifdef RT_ARCH_AMD64994 # ifdef RT_ARCH_AMD64 549 995 /* Don't allow 32-bit processes to do any I/O controls. */ 550 996 if (!IoIs32bitProcess(NULL)) 551 # endif997 # endif 552 998 { 553 999 /* … … 655 1101 } 656 1102 } 1103 # ifdef RT_ARCH_AMD64 1104 else 1105 { 1106 Log(("VBoxDrvNtFastIoDeviceControl: WOW64 req - not supported\n")); 1107 rcNt = STATUS_NOT_SUPPORTED; 1108 } 1109 # endif 1110 1111 /* complete the request. */ 1112 pIoStatus->Status = rcNt; 1113 pIoStatus->Information = cbOut; 1114 supdrvSessionRelease(pSession); 1115 return TRUE; /* handled. */ 1116 } 1117 #endif /* VBOXDRV_WITH_FAST_IO */ 1118 1119 1120 #ifdef VBOXDRV_WITH_FAST_IO 1121 /** 1122 * Fast I/O device control callback. 1123 * 1124 * This performs no buffering, neither on the way in or out. 1125 * 1126 * @returns TRUE if handled, FALSE if the normal I/O control routine should be 1127 * called. 1128 * @param pFileObj The file object. 1129 * @param fWait Whether it's a blocking call 1130 * @param pvInput The input buffer as specified by the user. 1131 * @param cbInput The size of the input buffer. 1132 * @param pvOutput The output buffer as specfied by the user. 1133 * @param cbOutput The size of the output buffer. 1134 * @param uFunction The function. 1135 * @param pIoStatus Where to return the status of the operation. 1136 * @param pDevObj The device object.. 1137 */ 1138 static BOOLEAN _stdcall VBoxDrvNtFastIoDeviceControl(PFILE_OBJECT pFileObj, BOOLEAN fWait, PVOID pvInput, ULONG cbInput, 1139 PVOID pvOutput, ULONG cbOutput, ULONG uCmd, 1140 PIO_STATUS_BLOCK pIoStatus, PDEVICE_OBJECT pDevObj) 1141 { 1142 PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj); 1143 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFileObj->FsContext; 1144 1145 /* 1146 * Check the input a little bit. 1147 */ 1148 if (!pSession) 1149 { 1150 pIoStatus->Status = STATUS_INVALID_PARAMETER; 1151 pIoStatus->Information = 0; 1152 return TRUE; 1153 } 1154 1155 /* 1156 * Deal with the 2-3 high-speed IOCtl that takes their arguments from 1157 * the session and iCmd, and does not return anything. 1158 */ 1159 if ( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN 1160 || uCmd == SUP_IOCTL_FAST_DO_HM_RUN 1161 || uCmd == SUP_IOCTL_FAST_DO_NOP) 1162 && pSession->fUnrestricted == true) 1163 { 1164 int rc = supdrvIOCtlFast(uCmd, (unsigned)(uintptr_t)pvOutput /* VMCPU id */, pDevExt, pSession); 1165 pIoStatus->Status = RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; 1166 pIoStatus->Information = 0; /* Could be used to pass rc if we liked. */ 1167 return TRUE; 1168 } 1169 1170 /* 1171 * The normal path. 1172 */ 1173 NTSTATUS rcNt; 1174 unsigned cbOut = 0; 1175 int rc = 0; 1176 Log2(("VBoxDrvNtFastIoDeviceControl(%p): ioctl=%#x pvIn=%p cbIn=%#x pvOut=%p cbOut=%#x pSession=%p\n", 1177 pDevExt, uCmd, pvInput, cbInput, pvOutput, cbOutput, pSession)); 1178 1179 #ifdef RT_ARCH_AMD64 1180 /* Don't allow 32-bit processes to do any I/O controls. */ 1181 if (!IoIs32bitProcess(NULL)) 1182 #endif 1183 { 1184 /* 1185 * In this fast I/O device control path we have to do our own buffering. 1186 */ 1187 /* Verify that the I/O control function matches our pattern. */ 1188 if ((uCmd & 0x3) == METHOD_BUFFERED) 1189 { 1190 /* Get the header so we can validate it a little bit against the 1191 parameters before allocating any memory kernel for the reqest. */ 1192 SUPREQHDR Hdr; 1193 if (cbInput >= sizeof(Hdr) && cbOutput >= sizeof(Hdr)) 1194 { 1195 __try 1196 { 1197 RtlCopyMemory(&Hdr, pvInput, sizeof(Hdr)); 1198 rcNt = STATUS_SUCCESS; 1199 } 1200 __except(EXCEPTION_EXECUTE_HANDLER) 1201 { 1202 rcNt = GetExceptionCode(); 1203 } 1204 } 1205 else 1206 rcNt = STATUS_INVALID_PARAMETER; 1207 if (NT_SUCCESS(rcNt)) 1208 { 1209 /* Verify that the sizes in the request header are correct. */ 1210 ULONG cbBuf = RT_MAX(cbInput, cbOutput); 1211 if ( cbInput == Hdr.cbIn 1212 && cbOutput == Hdr.cbOut 1213 && cbBuf < _1M*16) 1214 { 1215 /* Allocate a buffer and copy all the input into it. */ 1216 PSUPREQHDR pHdr = (PSUPREQHDR)ExAllocatePoolWithTag(NonPagedPool, cbBuf, 'VBox'); 1217 if (pHdr) 1218 { 1219 __try 1220 { 1221 RtlCopyMemory(pHdr, pvInput, cbInput); 1222 if (cbInput < cbBuf) 1223 RtlZeroMemory((uint8_t *)pHdr + cbInput, cbBuf - cbInput); 1224 rcNt = STATUS_SUCCESS; 1225 } 1226 __except(EXCEPTION_EXECUTE_HANDLER) 1227 { 1228 rcNt = GetExceptionCode(); 1229 } 1230 } 1231 else 1232 rcNt = STATUS_NO_MEMORY; 1233 if (NT_SUCCESS(rcNt)) 1234 { 1235 /* 1236 * Now call the common code to do the real work. 1237 */ 1238 rc = supdrvIOCtl(uCmd, pDevExt, pSession, pHdr); 1239 if (RT_SUCCESS(rc)) 1240 { 1241 /* 1242 * Copy back the result. 1243 */ 1244 cbOut = pHdr->cbOut; 1245 if (cbOut > cbOutput) 1246 { 1247 cbOut = cbOutput; 1248 OSDBGPRINT(("VBoxDrvNtFastIoDeviceControl: too much output! %#x > %#x; uCmd=%#x!\n", 1249 pHdr->cbOut, cbOut, uCmd)); 1250 } 1251 if (cbOut) 1252 { 1253 __try 1254 { 1255 RtlCopyMemory(pvOutput, pHdr, cbOut); 1256 rcNt = STATUS_SUCCESS; 1257 } 1258 __except(EXCEPTION_EXECUTE_HANDLER) 1259 { 1260 rcNt = GetExceptionCode(); 1261 } 1262 } 1263 else 1264 rcNt = STATUS_SUCCESS; 1265 } 1266 else if (rc == VERR_INVALID_PARAMETER) 1267 rcNt = STATUS_INVALID_PARAMETER; 1268 else 1269 rcNt = STATUS_NOT_SUPPORTED; 1270 Log2(("VBoxDrvNtFastIoDeviceControl: returns %#x cbOut=%d rc=%#x\n", rcNt, cbOut, rc)); 1271 } 1272 ExFreePoolWithTag(pHdr, 'VBox'); 1273 } 1274 else 1275 { 1276 Log(("VBoxDrvNtFastIoDeviceControl: Mismatching sizes (%#x) - Hdr=%#lx/%#lx Irp=%#lx/%#lx!\n", 1277 uCmd, Hdr.cbIn, Hdr.cbOut, cbInput, cbOutput)); 1278 rcNt = STATUS_INVALID_PARAMETER; 1279 } 1280 } 1281 } 1282 else 1283 { 1284 Log(("VBoxDrvNtFastIoDeviceControl: not buffered request (%#x) - not supported\n", uCmd)); 1285 rcNt = STATUS_NOT_SUPPORTED; 1286 } 1287 } 657 1288 #ifdef RT_ARCH_AMD64 658 1289 else … … 679 1310 NTSTATUS _stdcall VBoxDrvNtDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp) 680 1311 { 1312 VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(pDevObj, pIrp); 1313 681 1314 PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj); 682 1315 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); 683 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pStack->FileObject->FsContext; 1316 PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(), 1317 (PSUPDRVSESSION *)&pStack->FileObject->FsContext); 1318 1319 if (!RT_VALID_PTR(pSession)) 1320 return supdrvNtCompleteRequest(STATUS_TRUST_FAILURE, pIrp); 684 1321 685 1322 /* … … 687 1324 * the session and iCmd, and does not return anything. 688 1325 */ 689 ULONG ulCmd = pStack->Parameters.DeviceIoControl.IoControlCode; 690 if ( ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN 1326 if (pSession->fUnrestricted) 1327 { 1328 #if defined(VBOX_WITH_HARDENING) && !defined(VBOX_WITHOUT_DEBUGGER_CHECKS) 1329 if (supdrvNtIsDebuggerAttached()) 1330 { 1331 supdrvSessionRelease(pSession); 1332 return supdrvNtCompleteRequest(STATUS_TRUST_FAILURE, pIrp); 1333 } 1334 #endif 1335 1336 ULONG ulCmd = pStack->Parameters.DeviceIoControl.IoControlCode; 1337 if ( ulCmd == SUP_IOCTL_FAST_DO_RAW_RUN 691 1338 || ulCmd == SUP_IOCTL_FAST_DO_HM_RUN 692 1339 || ulCmd == SUP_IOCTL_FAST_DO_NOP) 693 && pSession->fUnrestricted == true) 694 { 695 int rc = supdrvIOCtlFast(ulCmd, (unsigned)(uintptr_t)pIrp->UserBuffer /* VMCPU id */, pDevExt, pSession); 696 697 /* Complete the I/O request. */ 698 NTSTATUS rcNt = pIrp->IoStatus.Status = RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; 699 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 700 return rcNt; 1340 { 1341 int rc = supdrvIOCtlFast(ulCmd, (unsigned)(uintptr_t)pIrp->UserBuffer /* VMCPU id */, pDevExt, pSession); 1342 1343 /* Complete the I/O request. */ 1344 supdrvSessionRelease(pSession); 1345 return supdrvNtCompleteRequest(RT_SUCCESS(rc) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER, pIrp); 1346 } 701 1347 } 702 1348 … … 787 1433 pIrp->IoStatus.Status = rcNt; 788 1434 pIrp->IoStatus.Information = cbOut; 1435 supdrvSessionRelease(pSession); 789 1436 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 790 1437 return rcNt; … … 800 1447 NTSTATUS _stdcall VBoxDrvNtInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp) 801 1448 { 1449 VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(pDevObj, pIrp); 1450 802 1451 PSUPDRVDEVEXT pDevExt = SUPDRVNT_GET_DEVEXT(pDevObj); 803 1452 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); … … 925 1574 RTPowerSignalEvent(((unsigned)pArgument2 == 0) ? RTPOWEREVENT_SUSPEND : RTPOWEREVENT_RESUME); 926 1575 } 1576 } 1577 1578 1579 /** 1580 * Called to clean up the session structure before it's freed. 1581 * 1582 * @param pDevExt The device globals. 1583 * @param pSession The session that's being cleaned up. 1584 */ 1585 void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession) 1586 { 1587 #ifdef VBOX_WITH_HARDENING 1588 if (pSession->pNtProtect) 1589 { 1590 supdrvNtProtectRelease(pSession->pNtProtect); 1591 pSession->pNtProtect = NULL; 1592 } 1593 #endif 1594 } 1595 1596 1597 void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 1598 { 1599 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 1600 } 1601 1602 1603 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser) 1604 { 1605 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser); 927 1606 } 928 1607 … … 1082 1761 rc = VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND; 1083 1762 break; 1084 case 0xC0000428 /* STATUS_INVALID_IMAGE_HASH */:1763 case /* 0xC0000428 */ STATUS_INVALID_IMAGE_HASH: 1085 1764 rc = VERR_LDR_IMAGE_HASH; 1086 1765 break; 1087 case 0xC000010E /* STATUS_IMAGE_ALREADY_LOADED */:1766 case /* 0xC000010E */ STATUS_IMAGE_ALREADY_LOADED: 1088 1767 Log(("WARNING: see @bugref{4853} for cause of this failure on Windows 7 x64\n")); 1089 1768 rc = VERR_ALREADY_LOADED; … … 1509 2188 } 1510 2189 2190 if (rc < 0) 2191 { 2192 if (((uint32_t)rc & UINT32_C(0xffff0000)) == UINT32_C(0xffff0000)) 2193 return (NTSTATUS)( ((uint32_t)rc & UINT32_C(0xffff)) 2194 | UINT32_C(0xe9860000) ); /* STATUS_SEVERITY_ERROR + C-bit + facility 0x986 */ 2195 } 1511 2196 return STATUS_UNSUCCESSFUL; 1512 2197 } … … 1547 2232 } 1548 2233 #endif 2234 2235 2236 #ifdef VBOX_WITH_HARDENING 2237 2238 /** @name Identifying Special Processes: CSRSS.EXE 2239 * @{ */ 2240 2241 2242 /** 2243 * Checks if the process is a system32 process by the given name. 2244 * 2245 * @returns true / false. 2246 * @param pProcess The process to check. 2247 * @param pszName The lower case process name (no path!). 2248 */ 2249 static bool supdrvNtProtectIsSystem32ProcessMatch(PEPROCESS pProcess, const char *pszName) 2250 { 2251 Assert(strlen(pszName) < 16); /* see buffer below */ 2252 2253 /* 2254 * This test works on XP+. 2255 */ 2256 const char *pszImageFile = (const char *)PsGetProcessImageFileName(pProcess); 2257 if (!pszImageFile) 2258 return false; 2259 2260 if (RTStrICmp(pszImageFile, pszName) != 0) 2261 return false; 2262 2263 /* 2264 * This test requires a Vista+ API. 2265 */ 2266 if (g_pfnPsReferenceProcessFilePointer) 2267 { 2268 PFILE_OBJECT pFile = NULL; 2269 NTSTATUS rcNt = g_pfnPsReferenceProcessFilePointer(pProcess, &pFile); 2270 if (!NT_SUCCESS(rcNt)) 2271 return false; 2272 2273 union 2274 { 2275 OBJECT_NAME_INFORMATION Info; 2276 uint8_t abBuffer[sizeof(g_System32NtPath) + 16 * sizeof(WCHAR)]; 2277 } Buf; 2278 ULONG cbIgn; 2279 rcNt = ObQueryNameString(pFile, &Buf.Info, sizeof(Buf) - sizeof(WCHAR), &cbIgn); 2280 ObDereferenceObject(pFile); 2281 if (!NT_SUCCESS(rcNt)) 2282 return false; 2283 2284 /* Terminate the name. */ 2285 PRTUTF16 pwszName = Buf.Info.Name.Buffer; 2286 pwszName[Buf.Info.Name.Length / sizeof(RTUTF16)] = '\0'; 2287 2288 /* Match the name against the system32 directory path. */ 2289 uint32_t cbSystem32 = g_System32NtPath.UniStr.Length; 2290 if (Buf.Info.Name.Length < cbSystem32) 2291 return false; 2292 if (memcmp(pwszName, g_System32NtPath.UniStr.Buffer, cbSystem32)) 2293 return false; 2294 pwszName += cbSystem32 / sizeof(RTUTF16); 2295 if (*pwszName++ != '\\') 2296 return false; 2297 2298 /* Compare the name. */ 2299 const char *pszRight = pszName; 2300 for (;;) 2301 { 2302 WCHAR wchLeft = *pwszName++; 2303 char chRight = *pszRight++; 2304 Assert(chRight == RT_C_TO_LOWER(chRight)); 2305 2306 if ( wchLeft != chRight 2307 && RT_C_TO_LOWER(wchLeft) != chRight) 2308 return false; 2309 if (!chRight) 2310 break; 2311 } 2312 } 2313 2314 return true; 2315 } 2316 2317 2318 /** 2319 * Checks if the current process is likely to be CSRSS. 2320 * 2321 * @returns true/false. 2322 * @param pProcess The process. 2323 */ 2324 static bool supdrvNtProtectIsCsrssByProcess(PEPROCESS pProcess) 2325 { 2326 /* 2327 * On Windows 8.1 CSRSS.EXE is a protected process. 2328 */ 2329 if (g_pfnPsIsProtectedProcessLight) 2330 { 2331 if (!g_pfnPsIsProtectedProcessLight(pProcess)) 2332 return false; 2333 } 2334 2335 /* 2336 * The name tests. 2337 */ 2338 if (!supdrvNtProtectIsSystem32ProcessMatch(pProcess, "csrss.exe")) 2339 return false; 2340 2341 /** @todo Could extend the CSRSS.EXE check with that the TokenUser of the 2342 * current process must be "NT AUTHORITY\SYSTEM" (S-1-5-18). */ 2343 2344 return true; 2345 } 2346 2347 2348 /** 2349 * Called in the context of VBoxDrvNtCreate to determin the CSRSS for the 2350 * current process. 2351 * 2352 * The Client/Server Runtime Subsystem (CSRSS) process needs to be allowed some 2353 * additional access right so we need to make 101% sure we correctly identify 2354 * the CSRSS process a process is associated with. 2355 * 2356 * @returns IPRT status code. 2357 * @param pNtProtect The NT protected process structure. The 2358 * hCsrssPid member will be updated on success. 2359 */ 2360 static int supdrvNtProtectFindAssociatedCsrss(PSUPDRVNTPROTECT pNtProtect) 2361 { 2362 Assert(pNtProtect->AvlCore.Key == PsGetCurrentProcessId()); 2363 Assert(pNtProtect->pCsrssProcess == NULL); 2364 Assert(pNtProtect->hCsrssPid == NULL); 2365 2366 /* 2367 * We'll try use the ApiPort LPC object for the session we're in to track 2368 * down the CSRSS process. So, we start by constructing a path to it. 2369 */ 2370 int rc; 2371 uint32_t uSessionId = PsGetProcessSessionId(PsGetCurrentProcess()); 2372 WCHAR wszApiPort[48]; 2373 if (uSessionId == 0) 2374 rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort"); 2375 else 2376 { 2377 char szTmp[64]; 2378 ssize_t cchTmp = RTStrFormatU32(szTmp, sizeof(szTmp), uSessionId, 10, 0, 0, 0); 2379 AssertReturn(cchTmp > 0, (int)cchTmp); 2380 rc = RTUtf16CopyAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Sessions\\"); 2381 if (RT_SUCCESS(rc)) 2382 rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), szTmp); 2383 if (RT_SUCCESS(rc)) 2384 rc = RTUtf16CatAscii(wszApiPort, RT_ELEMENTS(wszApiPort), "\\Windows\\ApiPort"); 2385 } 2386 AssertRCReturn(rc, rc); 2387 2388 UNICODE_STRING ApiPortStr; 2389 ApiPortStr.Buffer = wszApiPort; 2390 ApiPortStr.Length = (USHORT)(RTUtf16Len(wszApiPort) * sizeof(RTUTF16)); 2391 ApiPortStr.MaximumLength = ApiPortStr.Length + sizeof(RTUTF16); 2392 2393 /* 2394 * The object cannot be opened, but we can reference it by name. 2395 */ 2396 void *pvApiPortObj = NULL; 2397 NTSTATUS rcNt = ObReferenceObjectByName(&ApiPortStr, 2398 0, 2399 NULL /*pAccessState*/, 2400 STANDARD_RIGHTS_READ, 2401 *LpcPortObjectType, 2402 KernelMode, 2403 NULL /*pvParseContext*/, 2404 &pvApiPortObj); 2405 if (!NT_SUCCESS(rcNt)) 2406 { 2407 SUPR0Printf("vboxdrv: Error opening '%ls': %#x\n", wszApiPort, rcNt); 2408 return VERR_SUPDRV_APIPORT_OPEN_ERROR; 2409 } 2410 2411 /* 2412 * Query the processes in the system so we can locate CSRSS.EXE candidates. 2413 * Note! Attempts at using SystemSessionProcessInformation failed with 2414 * STATUS_ACCESS_VIOLATION. 2415 */ 2416 ULONG cbNeeded = _64K; 2417 uint32_t cbBuf; 2418 uint8_t *pbBuf = NULL; 2419 do 2420 { 2421 cbBuf = RT_ALIGN(cbNeeded + _4K, _64K); 2422 pbBuf = (uint8_t *)RTMemAlloc(cbBuf); 2423 if (!pbBuf) 2424 break; 2425 2426 cbNeeded = 0; 2427 #if 0 /* doesn't work. */ 2428 SYSTEM_SESSION_PROCESS_INFORMATION Req; 2429 Req.SessionId = uSessionId; 2430 Req.BufferLength = cbBuf; 2431 Req.Buffer = pbBuf; 2432 rcNt = NtQuerySystemInformation(SystemSessionProcessInformation, &Req, sizeof(Req), &cbNeeded); 2433 #else 2434 rcNt = NtQuerySystemInformation(SystemProcessInformation, pbBuf, cbBuf, &cbNeeded); 2435 #endif 2436 if (NT_SUCCESS(rcNt)) 2437 break; 2438 2439 RTMemFree(pbBuf); 2440 pbBuf = NULL; 2441 } while ( rcNt == STATUS_INFO_LENGTH_MISMATCH 2442 && cbNeeded > cbBuf 2443 && cbNeeded < 32U*_1M); 2444 2445 if ( pbBuf 2446 && NT_SUCCESS(rcNt) 2447 && cbNeeded >= sizeof(SYSTEM_PROCESS_INFORMATION)) 2448 { 2449 /* 2450 * Walk the returned data and look for the process associated with the 2451 * ApiPort object. The ApiPort object keeps the EPROCESS address of 2452 * the owner process (i.e. CSRSS) relatively early in the structure. On 2453 * 64-bit windows 8.1 it's at offset 0x18. So, obtain the EPROCESS 2454 * pointer to likely CSRSS processes and check for a match in the first 2455 * 0x40 bytes of the ApiPort object. 2456 */ 2457 rc = VERR_SUPDRV_CSRSS_NOT_FOUND; 2458 for (uint32_t offBuf = 0; offBuf <= cbNeeded - sizeof(SYSTEM_PROCESS_INFORMATION);) 2459 { 2460 PRTNT_SYSTEM_PROCESS_INFORMATION pProcInfo = (PRTNT_SYSTEM_PROCESS_INFORMATION)&pbBuf[offBuf]; 2461 if ( pProcInfo->ProcessName.Length == 9 * sizeof(WCHAR) 2462 && pProcInfo->NumberOfThreads > 2 /* Very low guess. */ 2463 && pProcInfo->HandleCount > 32 /* Very low guess, I hope. */ 2464 && (uintptr_t)pProcInfo->ProcessName.Buffer - (uintptr_t)pbBuf < cbNeeded 2465 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[0]) == 'c' 2466 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[1]) == 's' 2467 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[2]) == 'r' 2468 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[3]) == 's' 2469 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[4]) == 's' 2470 && pProcInfo->ProcessName.Buffer[5] == '.' 2471 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[6]) == 'e' 2472 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[7]) == 'x' 2473 && RT_C_TO_LOWER(pProcInfo->ProcessName.Buffer[8]) == 'e' ) 2474 { 2475 2476 /* Get the process structure and perform some more thorough 2477 process checks. */ 2478 PEPROCESS pProcess; 2479 rcNt = PsLookupProcessByProcessId(pProcInfo->UniqueProcessId, &pProcess); 2480 if (NT_SUCCESS(rcNt)) 2481 { 2482 if (supdrvNtProtectIsCsrssByProcess(pProcess)) 2483 { 2484 if (PsGetProcessSessionId(pProcess) == uSessionId) 2485 { 2486 /* Final test, check the ApiPort. 2487 Note! The old LPC (pre Vista) objects has the PID 2488 much earlier in the structure. Might be 2489 worth looking for it instead. */ 2490 bool fThatsIt = false; 2491 __try 2492 { 2493 PEPROCESS *ppPortProc = (PEPROCESS *)pvApiPortObj; 2494 uint32_t cTests = g_uNtVerCombined >= SUP_NT_VER_VISTA ? 16 : 38; /* ALPC since Vista. */ 2495 do 2496 { 2497 fThatsIt = *ppPortProc == pProcess; 2498 ppPortProc++; 2499 } while (!fThatsIt && --cTests > 0); 2500 } 2501 __except(EXCEPTION_EXECUTE_HANDLER) 2502 { 2503 fThatsIt = false; 2504 } 2505 if (fThatsIt) 2506 { 2507 /* Ok, we found it! Keep the process structure 2508 reference as well as the PID so we can 2509 safely identify it later on. */ 2510 pNtProtect->hCsrssPid = pProcInfo->UniqueProcessId; 2511 pNtProtect->pCsrssProcess = pProcess; 2512 rc = VINF_SUCCESS; 2513 break; 2514 } 2515 } 2516 } 2517 2518 ObDereferenceObject(pProcess); 2519 } 2520 } 2521 2522 /* Advance. */ 2523 if (!pProcInfo->NextEntryOffset) 2524 break; 2525 offBuf += pProcInfo->NextEntryOffset; 2526 } 2527 } 2528 else 2529 rc = VERR_SUPDRV_SESSION_PROCESS_ENUM_ERROR; 2530 RTMemFree(pbBuf); 2531 ObDereferenceObject(pvApiPortObj); 2532 return rc; 2533 } 2534 2535 2536 /** 2537 * Checks that the given process is the CSRSS process associated with protected 2538 * process. 2539 * 2540 * @returns true / false. 2541 * @param pNtProtect The NT protection structure. 2542 * @param pCsrss The process structure of the alleged CSRSS.EXE 2543 * process. 2544 */ 2545 static bool supdrvNtProtectIsAssociatedCsrss(PSUPDRVNTPROTECT pNtProtect, PEPROCESS pCsrss) 2546 { 2547 if (pNtProtect->pCsrssProcess == pCsrss) 2548 { 2549 if (pNtProtect->hCsrssPid == PsGetProcessId(pCsrss)) 2550 { 2551 return true; 2552 } 2553 } 2554 return false; 2555 } 2556 2557 2558 /** 2559 * Checks if the given process is the stupid themes service. 2560 * 2561 * The caller does some screening of access masks and what not. We do the rest. 2562 * 2563 * @returns true / false. 2564 * @param pNtProtect The NT protection structure. 2565 * @param pAnnoyingProcess The process structure of an process that might 2566 * happen to be the annoying themes process. 2567 */ 2568 static bool supdrvNtProtectIsFrigginThemesService(PSUPDRVNTPROTECT pNtProtect, PEPROCESS pAnnoyingProcess) 2569 { 2570 /* 2571 * Check the process name. 2572 */ 2573 if (!supdrvNtProtectIsSystem32ProcessMatch(pAnnoyingProcess, "svchost.exe")) 2574 return false; 2575 2576 /** @todo Come up with more checks. */ 2577 2578 return true; 2579 } 2580 2581 2582 /** @} */ 2583 2584 2585 /** @name Process Creation Callbacks. 2586 * @{ */ 2587 2588 /** 2589 * Common worker used by the process creation hooks as well as the process 2590 * handle creation hooks to check if a VM process is being created. 2591 * 2592 * @returns true if likely to be a VM process, false if not. 2593 * @param pNtStub The NT protection structure for the possible 2594 * stub process. 2595 * @param hParentPid The parent pid. 2596 * @param hChildPid The child pid. 2597 */ 2598 static bool supdrvNtProtectIsSpawningStubProcess(PSUPDRVNTPROTECT pNtStub, HANDLE hParentPid, HANDLE hChildPid) 2599 { 2600 bool fRc = false; 2601 if (pNtStub->AvlCore.Key == hParentPid) /* paranoia */ 2602 { 2603 if (pNtStub->enmProcessKind == kSupDrvNtProtectKind_StubSpawning) 2604 { 2605 /* Compare short names. */ 2606 PEPROCESS pStubProcess; 2607 NTSTATUS rcNt = PsLookupProcessByProcessId(hParentPid, &pStubProcess); 2608 if (NT_SUCCESS(rcNt)) 2609 { 2610 PEPROCESS pChildProcess; 2611 rcNt = PsLookupProcessByProcessId(hChildPid, &pChildProcess); 2612 if (NT_SUCCESS(rcNt)) 2613 { 2614 const char *pszStub = (const char *)PsGetProcessImageFileName(pStubProcess); 2615 const char *pszChild = (const char *)PsGetProcessImageFileName(pChildProcess); 2616 fRc = pszStub != NULL 2617 && pszChild != NULL 2618 && strcmp(pszStub, pszChild) == 0; 2619 2620 /** @todo check that the full image names matches. */ 2621 2622 ObDereferenceObject(pChildProcess); 2623 } 2624 ObDereferenceObject(pStubProcess); 2625 } 2626 } 2627 } 2628 return fRc; 2629 } 2630 2631 2632 /** 2633 * Common code used by the notifies to protect a child process. 2634 * 2635 * @returns VBox status code. 2636 * @param pNtStub The NT protect structure for the parent. 2637 * @param hChildPid The child pid. 2638 */ 2639 static int supdrvNtProtectProtectNewStubChild(PSUPDRVNTPROTECT pNtParent, HANDLE hChildPid) 2640 { 2641 /* 2642 * Create a child protection struction. 2643 */ 2644 PSUPDRVNTPROTECT pNtChild; 2645 int rc = supdrvNtProtectCreate(&pNtChild, hChildPid, kSupDrvNtProtectKind_VmProcessUnconfirmed, false /*fLink*/); 2646 if (RT_SUCCESS(rc)) 2647 { 2648 pNtChild->fFirstProcessCreateHandle = true; 2649 pNtChild->fFirstThreadCreateHandle = true; 2650 pNtChild->fCsrssFirstProcessCreateHandle = true; 2651 pNtChild->fCsrssFirstProcessDuplicateHandle = true; 2652 pNtChild->fThemesFirstProcessCreateHandle = true; 2653 pNtChild->hParentPid = pNtParent->AvlCore.Key; 2654 pNtChild->hCsrssPid = pNtParent->hCsrssPid; 2655 pNtChild->pCsrssProcess = pNtParent->pCsrssProcess; 2656 if (pNtChild->pCsrssProcess) 2657 ObReferenceObject(pNtChild->pCsrssProcess); 2658 2659 /* 2660 * Take the spinlock, recheck parent conditions and link things. 2661 */ 2662 RTSpinlockAcquire(g_hNtProtectLock); 2663 if (pNtParent->enmProcessKind == kSupDrvNtProtectKind_StubSpawning) 2664 { 2665 bool fSuccess = RTAvlPVInsert(&g_NtProtectTree, &pNtChild->AvlCore); 2666 if (fSuccess) 2667 { 2668 pNtParent->u.pChild = pNtChild; /* Parent keeps the initial reference. */ 2669 pNtParent->enmProcessKind = kSupDrvNtProtectKind_StubParent; 2670 pNtChild->u.pParent = pNtParent; 2671 2672 RTSpinlockRelease(g_hNtProtectLock); 2673 return VINF_SUCCESS; 2674 } 2675 2676 rc = VERR_INTERNAL_ERROR_2; 2677 } 2678 else 2679 rc = VERR_WRONG_ORDER; 2680 RTSpinlockRelease(g_hNtProtectLock); 2681 2682 supdrvNtProtectRelease(pNtChild); 2683 } 2684 return rc; 2685 } 2686 2687 2688 /** 2689 * Common process termination code. 2690 * 2691 * Transitions protected process to the dead states, protecting against handle 2692 * PID reuse (esp. with unconfirmed VM processes) and handle cleanup issues. 2693 * 2694 * @param hDeadPid The PID of the dead process. 2695 */ 2696 static void supdrvNtProtectUnprotectDeadProcess(HANDLE hDeadPid) 2697 { 2698 PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(hDeadPid); 2699 if (pNtProtect) 2700 { 2701 PSUPDRVNTPROTECT pNtChild = NULL; 2702 2703 RTSpinlockAcquire(g_hNtProtectLock); 2704 2705 /* 2706 * If this is an unconfirmed VM process, we must release the reference 2707 * the parent structure holds. 2708 */ 2709 if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed) 2710 { 2711 PSUPDRVNTPROTECT pNtParent = pNtProtect->u.pParent; 2712 AssertRelease(pNtParent); AssertRelease(pNtParent->u.pChild == pNtProtect); 2713 pNtParent->u.pChild = NULL; 2714 pNtProtect->u.pParent = NULL; 2715 pNtChild = pNtProtect; 2716 } 2717 /* 2718 * If this is a stub exitting before the VM process gets confirmed, 2719 * release the protection of the potential VM process as this is not 2720 * the prescribed behavior. 2721 */ 2722 else if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubParent 2723 && pNtProtect->u.pChild) 2724 { 2725 pNtChild = pNtProtect->u.pChild; 2726 pNtProtect->u.pChild = NULL; 2727 pNtChild->u.pParent = NULL; 2728 pNtChild->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead; 2729 } 2730 2731 /* 2732 * Transition it to the dead state to prevent it from opening the 2733 * support driver again or be posthumously abused as a vm process parent. 2734 */ 2735 if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed 2736 || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessConfirmed) 2737 pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead; 2738 else if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubParent 2739 || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubSpawning 2740 || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubUnverified) 2741 pNtProtect->enmProcessKind = kSupDrvNtProtectKind_StubDead; 2742 2743 RTSpinlockRelease(g_hNtProtectLock); 2744 2745 supdrvNtProtectRelease(pNtProtect); 2746 supdrvNtProtectRelease(pNtChild); 2747 2748 /* 2749 * Do session cleanups. 2750 */ 2751 AssertReturnVoid((HANDLE)(uintptr_t)RTProcSelf() == hDeadPid); 2752 if (g_pDevObjSys) 2753 { 2754 PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension; 2755 PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, (RTPROCESS)(uintptr_t)hDeadPid, 2756 RTR0ProcHandleSelf(), NULL); 2757 if (pSession) 2758 { 2759 supdrvSessionHashTabRemove(pDevExt, pSession, NULL); 2760 supdrvSessionRelease(pSession); /* Drops the reference from supdrvSessionHashTabLookup. */ 2761 } 2762 } 2763 } 2764 } 2765 2766 2767 /** 2768 * Common worker for the process creation callback that verifies a new child 2769 * being created by the handle creation callback code. 2770 * 2771 * @param pNtStub The parent. 2772 * @param pNtVm The child. 2773 * @param fCallerChecks The result of any additional tests the caller made. 2774 * This is in order to avoid duplicating the failure 2775 * path code. 2776 */ 2777 static void supdrvNtProtectVerifyNewChildProtection(PSUPDRVNTPROTECT pNtStub, PSUPDRVNTPROTECT pNtVm, bool fCallerChecks) 2778 { 2779 if ( fCallerChecks 2780 && pNtStub->enmProcessKind == kSupDrvNtProtectKind_StubParent 2781 && pNtVm->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed 2782 && pNtVm->u.pParent == pNtStub 2783 && pNtStub->u.pChild == pNtVm) 2784 { 2785 /* Fine, nothing to do. */ 2786 return; 2787 } 2788 2789 LogRel(("vboxdrv: Misdetected vm stub; hParentPid=%p hChildPid=%p\n", pNtStub->AvlCore.Key, pNtVm->AvlCore.Key)); 2790 if (pNtStub->enmProcessKind != kSupDrvNtProtectKind_VmProcessConfirmed) 2791 supdrvNtProtectUnprotectDeadProcess(pNtVm->AvlCore.Key); 2792 } 2793 2794 2795 /** 2796 * Old style callback (since forever). 2797 * 2798 * @param hParentPid The parent PID. 2799 * @param hNewPid The PID of the new child. 2800 * @param fCreated TRUE if it's a creation notification, 2801 * FALSE if termination. 2802 * @remarks ASSUMES this arrives before the handle creation callback. 2803 */ 2804 static VOID __stdcall 2805 supdrvNtProtectCallback_ProcessCreateNotify(HANDLE hParentPid, HANDLE hNewPid, BOOLEAN fCreated) 2806 { 2807 /* 2808 * Is it a new process that needs protection? 2809 */ 2810 if (fCreated) 2811 { 2812 PSUPDRVNTPROTECT pNtStub = supdrvNtProtectLookup(hParentPid); 2813 if (pNtStub) 2814 { 2815 PSUPDRVNTPROTECT pNtVm = supdrvNtProtectLookup(hNewPid); 2816 if (!pNtVm) 2817 { 2818 if (supdrvNtProtectIsSpawningStubProcess(pNtStub, hParentPid, hNewPid)) 2819 supdrvNtProtectProtectNewStubChild(pNtStub, hNewPid); 2820 } 2821 else 2822 { 2823 supdrvNtProtectVerifyNewChildProtection(pNtStub, pNtVm, true); 2824 supdrvNtProtectRelease(pNtVm); 2825 } 2826 supdrvNtProtectRelease(pNtStub); 2827 } 2828 } 2829 /* 2830 * Process termination, do clean ups. 2831 */ 2832 else 2833 supdrvNtProtectUnprotectDeadProcess(hNewPid); 2834 } 2835 2836 2837 /** 2838 * New style callback (Vista SP1+ / w2k8). 2839 * 2840 * @param pNewProcess The new process. 2841 * @param hNewPid The PID of the new process. 2842 * @param pInfo Process creation details. NULL if process 2843 * termination notification. 2844 * @remarks ASSUMES this arrives before the handle creation callback. 2845 */ 2846 static VOID __stdcall 2847 supdrvNtProtectCallback_ProcessCreateNotifyEx(PEPROCESS pNewProcess, HANDLE hNewPid, PPS_CREATE_NOTIFY_INFO pInfo) 2848 { 2849 /* 2850 * Is it a new process that needs protection? 2851 */ 2852 if (pInfo) 2853 { 2854 PSUPDRVNTPROTECT pNtStub = supdrvNtProtectLookup(pInfo->CreatingThreadId.UniqueProcess); 2855 2856 Log(("vboxdrv/NewProcessEx: ctx=%04zx/%p pid=%04zx ppid=%04zx ctor=%04zx/%04zx rcNt=%#x %.*ls\n", 2857 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 2858 hNewPid, pInfo->ParentProcessId, 2859 pInfo->CreatingThreadId.UniqueProcess, pInfo->CreatingThreadId.UniqueThread, pInfo->CreationStatus, 2860 pInfo->FileOpenNameAvailable && pInfo->ImageFileName ? (size_t)pInfo->ImageFileName->Length / 2 : 0, 2861 pInfo->FileOpenNameAvailable && pInfo->ImageFileName ? pInfo->ImageFileName->Buffer : NULL)); 2862 2863 if (pNtStub) 2864 { 2865 PSUPDRVNTPROTECT pNtVm = supdrvNtProtectLookup(hNewPid); 2866 if (!pNtVm) 2867 { 2868 /* Parent must be creator. */ 2869 if (pInfo->CreatingThreadId.UniqueProcess == pInfo->ParentProcessId) 2870 { 2871 if (supdrvNtProtectIsSpawningStubProcess(pNtStub, pInfo->ParentProcessId, hNewPid)) 2872 supdrvNtProtectProtectNewStubChild(pNtStub, hNewPid); 2873 } 2874 } 2875 else 2876 { 2877 /* Parent must be creator (as above). */ 2878 supdrvNtProtectVerifyNewChildProtection(pNtStub, pNtVm, 2879 pInfo->CreatingThreadId.UniqueProcess == pInfo->ParentProcessId); 2880 supdrvNtProtectRelease(pNtVm); 2881 } 2882 supdrvNtProtectRelease(pNtStub); 2883 } 2884 } 2885 /* 2886 * Process termination, do clean ups. 2887 */ 2888 else 2889 supdrvNtProtectUnprotectDeadProcess(hNewPid); 2890 } 2891 2892 /** @} */ 2893 2894 2895 /** @name Process Handle Callbacks. 2896 * @{ */ 2897 2898 /** Process rights that we allow for handles to stub and VM processes. */ 2899 # define SUPDRV_NT_ALLOW_PROCESS_RIGHTS \ 2900 ( PROCESS_TERMINATE \ 2901 | PROCESS_VM_READ \ 2902 | PROCESS_QUERY_INFORMATION \ 2903 | PROCESS_QUERY_LIMITED_INFORMATION \ 2904 | PROCESS_SUSPEND_RESUME \ 2905 | DELETE \ 2906 | READ_CONTROL \ 2907 | SYNCHRONIZE) 2908 2909 /** Evil process rights. */ 2910 # define SUPDRV_NT_EVIL_PROCESS_RIGHTS \ 2911 ( PROCESS_CREATE_THREAD \ 2912 | PROCESS_SET_SESSIONID /*?*/ \ 2913 | PROCESS_VM_OPERATION \ 2914 | PROCESS_VM_WRITE \ 2915 | PROCESS_DUP_HANDLE \ 2916 | PROCESS_CREATE_PROCESS /*?*/ \ 2917 | PROCESS_SET_QUOTA /*?*/ \ 2918 | PROCESS_SET_INFORMATION \ 2919 | PROCESS_SET_LIMITED_INFORMATION /*?*/ \ 2920 | 0) 2921 AssertCompile((SUPDRV_NT_ALLOW_PROCESS_RIGHTS & SUPDRV_NT_EVIL_PROCESS_RIGHTS) == 0); 2922 2923 2924 static OB_PREOP_CALLBACK_STATUS __stdcall 2925 supdrvNtProtectCallback_ProcessHandlePre(PVOID pvUser, POB_PRE_OPERATION_INFORMATION pOpInfo) 2926 { 2927 Assert(pvUser == NULL); 2928 Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE); 2929 Assert(pOpInfo->ObjectType == *PsProcessType); 2930 2931 /* 2932 * Protected? Kludge required for NtOpenProcess calls comming in before 2933 * the create process hook triggers on Windows 8.1 (possibly others too). 2934 */ 2935 HANDLE hObjPid = PsGetProcessId((PEPROCESS)pOpInfo->Object); 2936 PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(hObjPid); 2937 if (!pNtProtect) 2938 { 2939 HANDLE hParentPid = PsGetProcessInheritedFromUniqueProcessId((PEPROCESS)pOpInfo->Object); 2940 PSUPDRVNTPROTECT pNtStub = supdrvNtProtectLookup(hParentPid); 2941 if (pNtStub) 2942 { 2943 if (supdrvNtProtectIsSpawningStubProcess(pNtStub, hParentPid, hObjPid)) 2944 { 2945 supdrvNtProtectProtectNewStubChild(pNtStub, hObjPid); 2946 pNtProtect = supdrvNtProtectLookup(hObjPid); 2947 } 2948 supdrvNtProtectRelease(pNtStub); 2949 } 2950 } 2951 pOpInfo->CallContext = pNtProtect; /* Just for reference. */ 2952 if (pNtProtect) 2953 { 2954 /* 2955 * Ok, it's a protected process. Strip rights as required or possible. 2956 */ 2957 static ACCESS_MASK const s_fCsrssStupidDesires = 0x1fffff; 2958 ACCESS_MASK fAllowedRights = SUPDRV_NT_ALLOW_PROCESS_RIGHTS; 2959 2960 if (pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE) 2961 { 2962 /* Don't restrict the process accessing itself. */ 2963 if ((PEPROCESS)pOpInfo->Object == PsGetCurrentProcess()) 2964 { 2965 pOpInfo->CallContext = NULL; /* don't assert */ 2966 pNtProtect->fFirstProcessCreateHandle = false; 2967 2968 Log(("vboxdrv/ProcessHandlePre: ctx=%04zx/%p wants %#x to %p in pid=%04zx [%d] %s\n", 2969 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 2970 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess, 2971 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, 2972 PsGetProcessImageFileName(PsGetCurrentProcess()) )); 2973 } 2974 else 2975 { 2976 /* Special case 1 on Vista, 7 & 8: 2977 The CreateProcess code passes the handle over to CSRSS.EXE 2978 and the code inBaseSrvCreateProcess will duplicate the 2979 handle with 0x1fffff as access mask. NtDuplicateObject will 2980 fail this call before it ever gets down here. 2981 2982 Special case 2 on 8.1: 2983 The CreateProcess code requires additional rights for 2984 something, we'll drop these in the stub code. */ 2985 if ( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed 2986 && pNtProtect->fFirstProcessCreateHandle 2987 && pNtProtect->hParentPid == PsGetProcessId(PsGetCurrentProcess())) 2988 { 2989 if ( !pOpInfo->KernelHandle 2990 && pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == s_fCsrssStupidDesires) 2991 { 2992 if (g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 3)) 2993 fAllowedRights |= s_fCsrssStupidDesires; 2994 else 2995 fAllowedRights = fAllowedRights 2996 | PROCESS_VM_OPERATION 2997 | PROCESS_VM_WRITE 2998 | PROCESS_SET_INFORMATION 2999 | PROCESS_SET_LIMITED_INFORMATION 3000 | 0; 3001 pOpInfo->CallContext = NULL; /* don't assert this. */ 3002 } 3003 pNtProtect->fFirstProcessCreateHandle = false; 3004 } 3005 3006 /* Special case 3 on 8.1: 3007 The interaction between the CreateProcess code and CSRSS.EXE 3008 has changed to the better with Windows 8.1. CSRSS.EXE no 3009 longer duplicates the process (thread too) handle, but opens 3010 it, thus allowing us to do our job. */ 3011 if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 3) 3012 && pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed 3013 && pNtProtect->fCsrssFirstProcessCreateHandle 3014 && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) 3015 ) 3016 { 3017 pNtProtect->fCsrssFirstProcessCreateHandle = false; 3018 if (pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == s_fCsrssStupidDesires) 3019 { 3020 /* Not needed: PROCESS_CREATE_THREAD, PROCESS_SET_SESSIONID, 3021 PROCESS_CREATE_PROCESS */ 3022 fAllowedRights = fAllowedRights 3023 | PROCESS_VM_OPERATION 3024 | PROCESS_VM_WRITE 3025 | PROCESS_DUP_HANDLE /* Needed for CreateProcess/VBoxTestOGL. */ 3026 | 0; 3027 pOpInfo->CallContext = NULL; /* don't assert this. */ 3028 } 3029 } 3030 3031 /* Special case 4, Windows 7, Vista, possibly 8, but not 8.1: 3032 The Themes service requires PROCESS_DUP_HANDLE access to our 3033 process or we won't get any menus and dialogs will be half 3034 unreadable. This is _very_ unfortunate and more work will 3035 go into making this more secure. */ 3036 if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0) 3037 && g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 2) 3038 && pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == 0x1478 /* 6.1.7600.16385 (win7_rtm.090713-1255) */ 3039 && pNtProtect->fThemesFirstProcessCreateHandle 3040 && supdrvNtProtectIsFrigginThemesService(pNtProtect, PsGetCurrentProcess())) 3041 { 3042 pNtProtect->fThemesFirstProcessCreateHandle = true; /* Only once! */ 3043 fAllowedRights |= PROCESS_DUP_HANDLE; 3044 pOpInfo->CallContext = NULL; /* don't assert this. */ 3045 } 3046 3047 Log(("vboxdrv/ProcessHandlePre: ctx=%04zx/%p wants %#x to %p/pid=%04zx [%d], allow %#x => %#x; %s\n", 3048 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 3049 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess, 3050 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, fAllowedRights, 3051 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess & fAllowedRights, 3052 PsGetProcessImageFileName(PsGetCurrentProcess()))); 3053 3054 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess &= fAllowedRights; 3055 } 3056 } 3057 else 3058 { 3059 /* Don't restrict the process accessing itself. */ 3060 if ( (PEPROCESS)pOpInfo->Object == PsGetCurrentProcess() 3061 && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == pOpInfo->Object) 3062 { 3063 Log(("vboxdrv/ProcessHandlePre: ctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] %s\n", 3064 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 3065 pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess, 3066 PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess), 3067 pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess, 3068 pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess, 3069 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, 3070 PsGetProcessImageFileName(PsGetCurrentProcess()) )); 3071 3072 pOpInfo->CallContext = NULL; /* don't assert */ 3073 } 3074 else 3075 { 3076 /* Special case 5 on Vista, 7 & 8: 3077 This is the CSRSS.EXE end of special case #1. */ 3078 if ( g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 3) 3079 && pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed 3080 && pNtProtect->fCsrssFirstProcessDuplicateHandle 3081 && pNtProtect->hParentPid 3082 == PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess) 3083 && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == PsGetCurrentProcess() 3084 && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) 3085 ) 3086 { 3087 pNtProtect->fCsrssFirstProcessDuplicateHandle = false; 3088 if (pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess == s_fCsrssStupidDesires) 3089 { 3090 /* Not needed: PROCESS_CREATE_THREAD, PROCESS_SET_SESSIONID, 3091 PROCESS_CREATE_PROCESS, PROCESS_DUP_HANDLE */ 3092 fAllowedRights = fAllowedRights 3093 | PROCESS_VM_OPERATION 3094 | PROCESS_VM_WRITE 3095 | PROCESS_DUP_HANDLE /* Needed for launching VBoxTestOGL. */ 3096 | 0; 3097 pOpInfo->CallContext = NULL; /* don't assert this. */ 3098 } 3099 } 3100 3101 Log(("vboxdrv/ProcessHandlePre: ctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] %s\n", 3102 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 3103 pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess, 3104 PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess), 3105 pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess, 3106 pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess, 3107 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, 3108 PsGetProcessImageFileName(PsGetCurrentProcess()) )); 3109 3110 pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess &= fAllowedRights; 3111 } 3112 } 3113 supdrvNtProtectRelease(pNtProtect); 3114 } 3115 3116 return OB_PREOP_SUCCESS; 3117 } 3118 3119 3120 static VOID __stdcall 3121 supdrvNtProtectCallback_ProcessHandlePost(PVOID pvUser, POB_POST_OPERATION_INFORMATION pOpInfo) 3122 { 3123 Assert(pvUser == NULL); 3124 Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE); 3125 Assert(pOpInfo->ObjectType == *PsProcessType); 3126 3127 if ( pOpInfo->CallContext 3128 && NT_SUCCESS(pOpInfo->ReturnStatus)) 3129 { 3130 ACCESS_MASK const fGrantedAccess = pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE 3131 ? pOpInfo->Parameters->CreateHandleInformation.GrantedAccess 3132 : pOpInfo->Parameters->DuplicateHandleInformation.GrantedAccess; 3133 AssertReleaseMsg( !(fGrantedAccess & ~( SUPDRV_NT_ALLOW_PROCESS_RIGHTS 3134 | WRITE_OWNER | WRITE_DAC /* these two might be forced upon us */ 3135 | PROCESS_UNKNOWN_4000 /* Seen set on win 8.1 */ 3136 /*| PROCESS_UNKNOWN_8000 */ ) ) 3137 || pOpInfo->KernelHandle, 3138 ("GrantedAccess=%#x - we allow %#x - we did not allow %#x\n", 3139 fGrantedAccess, SUPDRV_NT_ALLOW_PROCESS_RIGHTS, fGrantedAccess & ~SUPDRV_NT_ALLOW_PROCESS_RIGHTS)); 3140 } 3141 } 3142 3143 # undef SUPDRV_NT_ALLOW_PROCESS_RIGHTS 3144 3145 /** @} */ 3146 3147 3148 /** @name Thread Handle Callbacks 3149 * @{ */ 3150 3151 /* From ntifs.h */ 3152 extern "C" NTKERNELAPI PEPROCESS __stdcall IoThreadToProcess(PETHREAD); 3153 3154 /** Thread rights that we allow for handles to stub and VM processes. */ 3155 # define SUPDRV_NT_ALLOWED_THREAD_RIGHTS \ 3156 ( THREAD_TERMINATE \ 3157 | THREAD_GET_CONTEXT \ 3158 | THREAD_QUERY_INFORMATION \ 3159 | THREAD_QUERY_LIMITED_INFORMATION \ 3160 | DELETE \ 3161 | READ_CONTROL \ 3162 | SYNCHRONIZE) 3163 /** @todo consider THREAD_SET_LIMITED_INFORMATION & THREAD_RESUME */ 3164 3165 /** Evil thread rights. 3166 * @remarks THREAD_RESUME is not included as it seems to be forced upon us by 3167 * Windows 8.1, at least for some processes. We dont' actively 3168 * allow it though, just tollerate it when forced to. */ 3169 # define SUPDRV_NT_EVIL_THREAD_RIGHTS \ 3170 ( THREAD_SUSPEND_RESUME \ 3171 | THREAD_SET_CONTEXT \ 3172 | THREAD_SET_INFORMATION \ 3173 | THREAD_SET_LIMITED_INFORMATION /*?*/ \ 3174 | THREAD_SET_THREAD_TOKEN /*?*/ \ 3175 | THREAD_IMPERSONATE /*?*/ \ 3176 | THREAD_DIRECT_IMPERSONATION /*?*/ \ 3177 /*| THREAD_RESUME - see remarks. */ \ 3178 | 0) 3179 AssertCompile((SUPDRV_NT_EVIL_THREAD_RIGHTS & SUPDRV_NT_ALLOWED_THREAD_RIGHTS) == 0); 3180 3181 3182 static OB_PREOP_CALLBACK_STATUS __stdcall 3183 supdrvNtProtectCallback_ThreadHandlePre(PVOID pvUser, POB_PRE_OPERATION_INFORMATION pOpInfo) 3184 { 3185 Assert(pvUser == NULL); 3186 Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE); 3187 Assert(pOpInfo->ObjectType == *PsThreadType); 3188 3189 PEPROCESS pProcess = IoThreadToProcess((PETHREAD)pOpInfo->Object); 3190 PSUPDRVNTPROTECT pNtProtect = supdrvNtProtectLookup(PsGetProcessId(pProcess)); 3191 pOpInfo->CallContext = pNtProtect; /* Just for reference. */ 3192 if (pNtProtect) 3193 { 3194 static ACCESS_MASK const s_fCsrssStupidDesires = 0x1fffff; 3195 ACCESS_MASK fAllowedRights = SUPDRV_NT_ALLOWED_THREAD_RIGHTS; 3196 3197 if (pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE) 3198 { 3199 /* Don't restrict the process accessing its own threads. */ 3200 if (pProcess == PsGetCurrentProcess()) 3201 { 3202 Log(("vboxdrv/ThreadHandlePre: ctx=%04zx/%p wants %#x to %p in pid=%04zx [%d] self\n", 3203 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 3204 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess, 3205 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind)); 3206 pOpInfo->CallContext = NULL; /* don't assert */ 3207 pNtProtect->fFirstThreadCreateHandle = false; 3208 } 3209 else 3210 { 3211 /* Special case 1 on Vista, 7, 8: 3212 The CreateProcess code passes the handle over to CSRSS.EXE 3213 and the code inBaseSrvCreateProcess will duplicate the 3214 handle with 0x1fffff as access mask. NtDuplicateObject will 3215 fail this call before it ever gets down here. */ 3216 if ( g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 3) 3217 && pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed 3218 && pNtProtect->fFirstThreadCreateHandle 3219 && pNtProtect->hParentPid == PsGetProcessId(PsGetCurrentProcess())) 3220 { 3221 if ( !pOpInfo->KernelHandle 3222 && pOpInfo->Parameters->CreateHandleInformation.DesiredAccess == s_fCsrssStupidDesires) 3223 { 3224 fAllowedRights |= s_fCsrssStupidDesires; 3225 pOpInfo->CallContext = NULL; /* don't assert this. */ 3226 } 3227 pNtProtect->fFirstThreadCreateHandle = false; 3228 } 3229 3230 /* Special case 2 on 8.1, possibly also Vista, 7, 8: 3231 When creating a process like VBoxTestOGL from the VM process, 3232 CSRSS.EXE will try talk to the calling thread and, it 3233 appears, impersonate it. We unfortunately need to allow 3234 this or there will be no 3D support. Typical DbgPrint: 3235 "SXS: BasepCreateActCtx() Calling csrss server failed. Status = 0xc00000a5" */ 3236 SUPDRVNTPROTECTKIND enmProcessKind; 3237 if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 0, 0, 0) 3238 && ( (enmProcessKind = pNtProtect->enmProcessKind) == kSupDrvNtProtectKind_VmProcessConfirmed 3239 || enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed) 3240 && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) ) 3241 { 3242 fAllowedRights |= THREAD_IMPERSONATE; 3243 fAllowedRights |= THREAD_DIRECT_IMPERSONATION; 3244 //fAllowedRights |= THREAD_SET_LIMITED_INFORMATION; - try without this one 3245 pOpInfo->CallContext = NULL; /* don't assert this. */ 3246 } 3247 3248 Log(("vboxdrv/ThreadHandlePre: ctx=%04zx/%p wants %#x to %p in pid=%04zx [%d], allow %#x => %#x; %s\n", 3249 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 3250 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess, 3251 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, fAllowedRights, 3252 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess & fAllowedRights, 3253 PsGetProcessImageFileName(PsGetCurrentProcess()))); 3254 3255 pOpInfo->Parameters->CreateHandleInformation.DesiredAccess &= fAllowedRights; 3256 } 3257 } 3258 else 3259 { 3260 /* Don't restrict the process accessing its own threads. */ 3261 if ( pProcess == PsGetCurrentProcess() 3262 && (PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == pProcess) 3263 { 3264 Log(("vboxdrv/ThreadHandlePre: ctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d] self\n", 3265 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 3266 pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess, 3267 PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess), 3268 pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess, 3269 pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess, 3270 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, 3271 PsGetProcessImageFileName(PsGetCurrentProcess()) )); 3272 pOpInfo->CallContext = NULL; /* don't assert */ 3273 } 3274 else 3275 { 3276 /* Special case 3 on Vista, 7, 8: 3277 This is the follow up to special case 1. */ 3278 SUPDRVNTPROTECTKIND enmProcessKind; 3279 if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 0, 0, 0) 3280 && ( (enmProcessKind = pNtProtect->enmProcessKind) == kSupDrvNtProtectKind_VmProcessConfirmed 3281 || enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed) 3282 && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == PsGetCurrentProcess() 3283 && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) ) 3284 { 3285 fAllowedRights |= THREAD_IMPERSONATE; 3286 fAllowedRights |= THREAD_DIRECT_IMPERSONATION; 3287 //fAllowedRights |= THREAD_SET_LIMITED_INFORMATION; - try without this one 3288 pOpInfo->CallContext = NULL; /* don't assert this. */ 3289 } 3290 3291 Log(("vboxdrv/ThreadHandlePre: ctx=%04zx/%p[%p] dup from %04zx/%p with %#x to %p in pid=%04zx [%d], allow %#x => %#x; %s\n", 3292 PsGetProcessId(PsGetCurrentProcess()), PsGetCurrentProcess(), 3293 pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess, 3294 PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess), 3295 pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess, 3296 pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess, 3297 pOpInfo->Object, pNtProtect->AvlCore.Key, pNtProtect->enmProcessKind, fAllowedRights, 3298 pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess & fAllowedRights, 3299 PsGetProcessImageFileName(PsGetCurrentProcess()) )); 3300 3301 pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess &= fAllowedRights; 3302 } 3303 } 3304 3305 supdrvNtProtectRelease(pNtProtect); 3306 } 3307 3308 return OB_PREOP_SUCCESS; 3309 } 3310 3311 3312 static VOID __stdcall 3313 supdrvNtProtectCallback_ThreadHandlePost(PVOID pvUser, POB_POST_OPERATION_INFORMATION pOpInfo) 3314 { 3315 Assert(pvUser == NULL); 3316 Assert(pOpInfo->Operation == OB_OPERATION_HANDLE_CREATE || pOpInfo->Operation == OB_OPERATION_HANDLE_DUPLICATE); 3317 Assert(pOpInfo->ObjectType == *PsThreadType); 3318 3319 if ( pOpInfo->CallContext 3320 && NT_SUCCESS(pOpInfo->ReturnStatus)) 3321 { 3322 ACCESS_MASK const fGrantedAccess = pOpInfo->Parameters->CreateHandleInformation.GrantedAccess; 3323 AssertReleaseMsg( !(fGrantedAccess & ~( SUPDRV_NT_ALLOWED_THREAD_RIGHTS 3324 | WRITE_OWNER | WRITE_DAC /* these two might be forced upon us */ 3325 | THREAD_RESUME /* This seems to be force upon us too with 8.1. */ 3326 ) ) 3327 || pOpInfo->KernelHandle, 3328 ("GrantedAccess=%#x - we allow %#x - we did not allow %#x\n", 3329 fGrantedAccess, SUPDRV_NT_ALLOWED_THREAD_RIGHTS, fGrantedAccess & ~SUPDRV_NT_ALLOWED_THREAD_RIGHTS)); 3330 } 3331 } 3332 3333 # undef SUPDRV_NT_ALLOWED_THREAD_RIGHTS 3334 3335 /** @} */ 3336 3337 3338 /** 3339 * Creates a new process protection structure. 3340 * 3341 * @returns VBox status code. 3342 * @param ppNtProtect Where to return the pointer to the structure 3343 * on success. 3344 * @param hPid The process ID of the process to protect. 3345 * @param enmProcessKind The kind of process we're protecting. 3346 * @param fLink Whether to link the structure into the tree. 3347 */ 3348 static int supdrvNtProtectCreate(PSUPDRVNTPROTECT *ppNtProtect, HANDLE hPid, SUPDRVNTPROTECTKIND enmProcessKind, bool fLink) 3349 { 3350 AssertReturn(g_hNtProtectLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER); 3351 3352 PSUPDRVNTPROTECT pNtProtect = (PSUPDRVNTPROTECT)RTMemAllocZ(sizeof(*pNtProtect)); 3353 if (!pNtProtect) 3354 return VERR_NO_MEMORY; 3355 3356 pNtProtect->AvlCore.Key = hPid; 3357 pNtProtect->u32Magic = SUPDRVNTPROTECT_MAGIC; 3358 pNtProtect->cRefs = 1; 3359 pNtProtect->enmProcessKind = enmProcessKind; 3360 pNtProtect->hParentPid = NULL; 3361 pNtProtect->hCsrssPid = NULL; 3362 pNtProtect->pCsrssProcess = NULL; 3363 3364 if (fLink) 3365 { 3366 RTSpinlockAcquire(g_hNtProtectLock); 3367 bool fSuccess = RTAvlPVInsert(&g_NtProtectTree, &pNtProtect->AvlCore); 3368 RTSpinlockRelease(g_hNtProtectLock); 3369 3370 if (!fSuccess) 3371 { 3372 /* Duplicate entry, fail. */ 3373 pNtProtect->u32Magic = SUPDRVNTPROTECT_MAGIC_DEAD; 3374 RTMemFree(pNtProtect); 3375 return VERR_ACCESS_DENIED; 3376 } 3377 } 3378 3379 *ppNtProtect = pNtProtect; 3380 return VINF_SUCCESS; 3381 } 3382 3383 3384 /** 3385 * Releases a reference to a NT protection structure. 3386 * 3387 * @param pNtProtect The NT protection structure. 3388 */ 3389 static void supdrvNtProtectRelease(PSUPDRVNTPROTECT pNtProtect) 3390 { 3391 if (!pNtProtect) 3392 return; 3393 AssertReturnVoid(pNtProtect->u32Magic == SUPDRVNTPROTECT_MAGIC); 3394 3395 RTSpinlockAcquire(g_hNtProtectLock); 3396 uint32_t cRefs = ASMAtomicDecU32(&pNtProtect->cRefs); 3397 if (cRefs != 0) 3398 RTSpinlockRelease(g_hNtProtectLock); 3399 else 3400 { 3401 /* 3402 * That was the last reference. Remove it from the tree, invalidate it 3403 * and free the resources associated with it. Also, release any 3404 * child/parent references related to this protection structure. 3405 */ 3406 ASMAtomicWriteU32(&pNtProtect->u32Magic, SUPDRVNTPROTECT_MAGIC_DEAD); 3407 PSUPDRVNTPROTECT pRemoved = (PSUPDRVNTPROTECT)RTAvlPVRemove(&g_NtProtectTree, pNtProtect->AvlCore.Key); 3408 3409 PSUPDRVNTPROTECT pRemovedChild = NULL; 3410 PSUPDRVNTPROTECT pChild = NULL; 3411 if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubParent) 3412 { 3413 pChild = pNtProtect->u.pChild; 3414 if (pChild) 3415 { 3416 pNtProtect->u.pChild = NULL; 3417 pChild->u.pParent = NULL; 3418 pChild->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead; 3419 uint32_t cChildRefs = ASMAtomicIncU32(&pChild->cRefs); 3420 if (!cChildRefs) 3421 pRemovedChild = (PSUPDRVNTPROTECT)RTAvlPVRemove(&g_NtProtectTree, pChild->AvlCore.Key); 3422 else 3423 pChild = NULL; 3424 } 3425 } 3426 else 3427 AssertRelease(pNtProtect->enmProcessKind != kSupDrvNtProtectKind_VmProcessUnconfirmed); 3428 3429 RTSpinlockRelease(g_hNtProtectLock); 3430 Assert(pRemoved == pNtProtect); 3431 Assert(pRemovedChild == pChild); 3432 3433 if (pNtProtect->pCsrssProcess) 3434 { 3435 ObDereferenceObject(pNtProtect->pCsrssProcess); 3436 pNtProtect->pCsrssProcess = NULL; 3437 } 3438 3439 RTMemFree(pNtProtect); 3440 if (pChild) 3441 RTMemFree(pChild); 3442 } 3443 } 3444 3445 3446 /** 3447 * Looks up a PID in the NT protect tree. 3448 * 3449 * @returns Pointer to a NT protection structure (with a referenced) on success, 3450 * NULL if not found. 3451 * @param hPid The process ID. 3452 */ 3453 static PSUPDRVNTPROTECT supdrvNtProtectLookup(HANDLE hPid) 3454 { 3455 RTSpinlockAcquire(g_hNtProtectLock); 3456 PSUPDRVNTPROTECT pFound = (PSUPDRVNTPROTECT)RTAvlPVGet(&g_NtProtectTree, hPid); 3457 if (pFound) 3458 ASMAtomicIncU32(&pFound->cRefs); 3459 RTSpinlockRelease(g_hNtProtectLock); 3460 return pFound; 3461 } 3462 3463 3464 /** 3465 * Worker for supdrvNtProtectVerifyProcess that verifies the handles to a VM 3466 * process and its thread. 3467 * 3468 * @returns VBox status code. 3469 * @param pNtProtect The NT protect structure for getting information 3470 * about special processes. 3471 */ 3472 static int supdrvNtProtectRestrictHandlesToProcessAndThread(PSUPDRVNTPROTECT pNtProtect) 3473 { 3474 /* 3475 * What to protect. 3476 */ 3477 PEPROCESS pProtectedProcess = PsGetCurrentProcess(); 3478 HANDLE hProtectedPid = PsGetProcessId(pProtectedProcess); 3479 PETHREAD pProtectedThread = PsGetCurrentThread(); 3480 AssertReturn(pNtProtect->AvlCore.Key == hProtectedPid, VERR_INTERNAL_ERROR_5); 3481 3482 /* 3483 * Take a snapshot of all the handles in the system. 3484 */ 3485 uint32_t cbBuf = _256K; 3486 uint8_t *pbBuf = (uint8_t *)RTMemAlloc(cbBuf); 3487 ULONG cbNeeded = cbBuf; 3488 NTSTATUS rcNt = NtQuerySystemInformation(SystemExtendedHandleInformation, pbBuf, cbBuf, &cbNeeded); 3489 if (!NT_SUCCESS(rcNt)) 3490 { 3491 while ( rcNt == STATUS_INFO_LENGTH_MISMATCH 3492 && cbNeeded > cbBuf 3493 && cbBuf <= 32U*_1M) 3494 { 3495 cbBuf = RT_ALIGN_32(cbNeeded + _4K, _64K); 3496 RTMemFree(pbBuf); 3497 pbBuf = (uint8_t *)RTMemAlloc(cbBuf); 3498 if (!pbBuf) 3499 return VERR_NO_MEMORY; 3500 rcNt = NtQuerySystemInformation(SystemExtendedHandleInformation, pbBuf, cbBuf, &cbNeeded); 3501 } 3502 if (!NT_SUCCESS(rcNt)) 3503 { 3504 RTMemFree(pbBuf); 3505 return RTErrConvertFromNtStatus(rcNt); 3506 } 3507 } 3508 3509 /* 3510 * Walk the information and look for handles to the two objects we're protecting. 3511 */ 3512 int rc = VINF_SUCCESS; 3513 3514 uint32_t cCsrssProcessHandles = 0; 3515 uint32_t cSystemProcessHandles = 0; 3516 uint32_t cEvilProcessHandles = 0; 3517 uint32_t cBenignProcessHandles = 0; 3518 3519 uint32_t cCsrssThreadHandles = 0; 3520 uint32_t cEvilThreadHandles = 0; 3521 uint32_t cBenignThreadHandles = 0; 3522 3523 SYSTEM_HANDLE_INFORMATION_EX const *pInfo = (SYSTEM_HANDLE_INFORMATION_EX const *)pbBuf; 3524 ULONG_PTR i = pInfo->NumberOfHandles; 3525 AssertRelease(RT_OFFSETOF(SYSTEM_HANDLE_INFORMATION_EX, Handles[i]) == cbNeeded); 3526 while (i-- > 0) 3527 { 3528 const char *pszType; 3529 SYSTEM_HANDLE_ENTRY_INFO_EX const *pHandleInfo = &pInfo->Handles[i]; 3530 if (pHandleInfo->Object == pProtectedProcess) 3531 { 3532 /* Handles within the protected process is fine. */ 3533 if ( !(pHandleInfo->GrantedAccess & SUPDRV_NT_EVIL_PROCESS_RIGHTS) 3534 || pHandleInfo->UniqueProcessId == hProtectedPid) 3535 { 3536 cBenignProcessHandles++; 3537 continue; 3538 } 3539 3540 /* CSRSS is allowed to have one evil process handle. 3541 See the special cases in the hook code. */ 3542 if ( cCsrssProcessHandles < 1 3543 && pHandleInfo->UniqueProcessId == pNtProtect->hCsrssPid) 3544 { 3545 cCsrssProcessHandles++; 3546 continue; 3547 } 3548 3549 /* The system process is allowed having one open process handle in 3550 Windows 8.1 and later. */ 3551 if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 3) 3552 && cSystemProcessHandles < 1 3553 && pHandleInfo->UniqueProcessId == PsGetProcessId(PsInitialSystemProcess)) 3554 { 3555 cSystemProcessHandles++; 3556 continue; 3557 } 3558 3559 cEvilProcessHandles++; 3560 pszType = "process"; 3561 } 3562 else if (pHandleInfo->Object == pProtectedThread) 3563 { 3564 /* Handles within the protected process is fine. */ 3565 if ( !(pHandleInfo->GrantedAccess & SUPDRV_NT_EVIL_THREAD_RIGHTS) 3566 || pHandleInfo->UniqueProcessId == hProtectedPid) 3567 { 3568 cBenignThreadHandles++; 3569 continue; 3570 } 3571 3572 /* CSRSS is allowed to have one evil handle to the primary thread 3573 for LPC purposes. See the hook for special case. */ 3574 if ( cCsrssThreadHandles < 1 3575 && pHandleInfo->UniqueProcessId == pNtProtect->hCsrssPid) 3576 { 3577 cCsrssThreadHandles++; 3578 continue; 3579 } 3580 3581 cEvilThreadHandles++; 3582 pszType = "thread"; 3583 } 3584 else 3585 continue; 3586 3587 /* Found evil handle. Currently ignoring on pre-Vista. */ 3588 # ifndef VBOX_WITH_VISTA_NO_SP 3589 if ( g_uNtVerCombined >= SUP_NT_VER_VISTA 3590 # else 3591 if ( g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 6001, 0, 0) 3592 # endif 3593 || g_pfnObRegisterCallbacks) 3594 { 3595 LogRel(("vboxdrv: Found evil handle to budding VM process: pid=%p h=%p acc=%#x attr=%#x type=%s\n", 3596 pHandleInfo->UniqueProcessId, pHandleInfo->HandleValue, 3597 pHandleInfo->GrantedAccess, pHandleInfo->HandleAttributes, pszType)); 3598 rc = VERR_SUPDRV_HARDENING_EVIL_HANDLE; 3599 } 3600 } 3601 3602 return rc; 3603 } 3604 3605 3606 /** 3607 * Checks if the current process checks out as a VM process stub. 3608 * 3609 * @returns VBox status code. 3610 * @param pNtProtect The NT protect structure. This is upgraded to a 3611 * final protection kind (state) on success. 3612 */ 3613 static int supdrvNtProtectVerifyProcess(PSUPDRVNTPROTECT pNtProtect) 3614 { 3615 AssertReturn(PsGetProcessId(PsGetCurrentProcess()) == pNtProtect->AvlCore.Key, VERR_INTERNAL_ERROR_3); 3616 3617 /* 3618 * Do the verification. The handle restriction checks are only preformed 3619 * on VM processes. 3620 */ 3621 int rc = VINF_SUCCESS; 3622 if (pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed) 3623 rc = supdrvNtProtectRestrictHandlesToProcessAndThread(pNtProtect); 3624 if (RT_SUCCESS(rc)) 3625 { 3626 char szErr[256]; 3627 RT_ZERO(szErr); 3628 RTERRINFO ErrInfo; 3629 RTErrInfoInit(&ErrInfo, szErr, sizeof(szErr)); 3630 3631 rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), &ErrInfo); 3632 if (RT_FAILURE(rc)) 3633 RTLogWriteDebugger(szErr, strlen(szErr)); 3634 } 3635 3636 /* 3637 * Upgrade and return. 3638 */ 3639 RTSpinlockAcquire(g_hNtProtectLock); 3640 3641 /* Stub process verficiation is pretty much straight forward. */ 3642 if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubUnverified) 3643 pNtProtect->enmProcessKind = RT_SUCCESS(rc) ? kSupDrvNtProtectKind_StubSpawning : kSupDrvNtProtectKind_StubDead; 3644 3645 /* The VM process verification is a little bit more complicated 3646 because we need to drop the parent process reference as well. */ 3647 else if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed) 3648 { 3649 AssertRelease(pNtProtect->cRefs >= 2); /* Parent + Caller */ 3650 PSUPDRVNTPROTECT pParent = pNtProtect->u.pParent; 3651 AssertRelease(pParent); 3652 AssertRelease(pParent->u.pParent == pNtProtect); 3653 AssertRelease(pParent->enmProcessKind == kSupDrvNtProtectKind_StubParent); 3654 pParent->u.pParent = NULL; 3655 3656 pNtProtect->u.pParent = NULL; 3657 ASMAtomicDecU32(&pNtProtect->cRefs); 3658 3659 if (RT_SUCCESS(rc)) 3660 pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessConfirmed; 3661 else 3662 pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead; 3663 } 3664 3665 /* Since the stub and VM processes are only supposed to have one thread, 3666 we're not supposed to be subject to any races from within the processes. 3667 3668 There is a race between VM process verification and the stub process 3669 exiting, though. We require the stub process to be alive until the new 3670 VM process has made it thru the validation. So, when the stub 3671 terminates the notification handler will change the state of both stub 3672 and VM process to dead. 3673 3674 Also, I'm not entirely certain where the process 3675 termination notification is triggered from, so that can theorically 3676 create a race in both cases. */ 3677 else 3678 { 3679 AssertReleaseMsg( pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubDead 3680 || pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessDead, 3681 ("enmProcessKind=%d rc=%Rrc\n", pNtProtect->enmProcessKind, rc)); 3682 if (RT_SUCCESS(rc)) 3683 rc = VERR_INVALID_STATE; /* There should be no races here. */ 3684 } 3685 3686 RTSpinlockRelease(g_hNtProtectLock); 3687 return rc; 3688 } 3689 3690 3691 # ifndef VBOX_WITHOUT_DEBUGGER_CHECKS 3692 3693 /** 3694 * Checks if the current process is being debugged. 3695 * @return @c true if debugged, @c false if not. 3696 */ 3697 static bool supdrvNtIsDebuggerAttached(void) 3698 { 3699 return PsIsProcessBeingDebugged(PsGetCurrentProcess()) != FALSE; 3700 } 3701 3702 # endif /* !VBOX_WITHOUT_DEBUGGER_CHECKS */ 3703 3704 3705 /** 3706 * Terminates the hardening bits. 3707 */ 3708 static void supdrvNtProtectTerm(void) 3709 { 3710 /* 3711 * Stop intercepting process and thread handle creation calls. 3712 */ 3713 if (g_pvObCallbacksCookie) 3714 { 3715 g_pfnObUnRegisterCallbacks(g_pvObCallbacksCookie); 3716 g_pvObCallbacksCookie = NULL; 3717 } 3718 3719 /* 3720 * Stop intercepting process creation and termination notifications. 3721 */ 3722 NTSTATUS rcNt; 3723 if (g_pfnPsSetCreateProcessNotifyRoutineEx) 3724 rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/); 3725 else 3726 rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, TRUE /*fRemove*/); 3727 AssertMsg(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt)); 3728 3729 Assert(g_NtProtectTree == NULL); 3730 3731 /* 3732 * Clean up globals. 3733 */ 3734 RTSpinlockDestroy(g_hNtProtectLock); 3735 g_NtProtectTree = NIL_RTSPINLOCK; 3736 3737 supHardenedWinTermImageVerifier(); 3738 } 3739 3740 # ifdef RT_ARCH_X86 3741 DECLASM(void) supdrvNtQueryVirtualMemory_0xAF(void); 3742 DECLASM(void) supdrvNtQueryVirtualMemory_0xB0(void); 3743 DECLASM(void) supdrvNtQueryVirtualMemory_0xB1(void); 3744 DECLASM(void) supdrvNtQueryVirtualMemory_0xB2(void); 3745 DECLASM(void) supdrvNtQueryVirtualMemory_0xB3(void); 3746 DECLASM(void) supdrvNtQueryVirtualMemory_0xB4(void); 3747 DECLASM(void) supdrvNtQueryVirtualMemory_0xB5(void); 3748 DECLASM(void) supdrvNtQueryVirtualMemory_0xB6(void); 3749 DECLASM(void) supdrvNtQueryVirtualMemory_0xB7(void); 3750 DECLASM(void) supdrvNtQueryVirtualMemory_0xB8(void); 3751 DECLASM(void) supdrvNtQueryVirtualMemory_0xB9(void); 3752 DECLASM(void) supdrvNtQueryVirtualMemory_0xBA(void); 3753 DECLASM(void) supdrvNtQueryVirtualMemory_0xBB(void); 3754 DECLASM(void) supdrvNtQueryVirtualMemory_0xBC(void); 3755 DECLASM(void) supdrvNtQueryVirtualMemory_0xBD(void); 3756 DECLASM(void) supdrvNtQueryVirtualMemory_0xBE(void); 3757 # elif defined(RT_ARCH_AMD64) 3758 DECLASM(void) supdrvNtQueryVirtualMemory_0x1F(void); 3759 DECLASM(void) supdrvNtQueryVirtualMemory_0x20(void); 3760 DECLASM(void) supdrvNtQueryVirtualMemory_0x21(void); 3761 DECLASM(void) supdrvNtQueryVirtualMemory_0x22(void); 3762 DECLASM(void) supdrvNtQueryVirtualMemory_0x23(void); 3763 extern "C" NTSYSAPI NTSTATUS NTAPI ZwRequestWaitReplyPort(HANDLE, PVOID, PVOID); 3764 # endif 3765 3766 /** 3767 * Initalizes the hardening bits. 3768 * 3769 * @returns NT status code. 3770 */ 3771 static NTSTATUS supdrvNtProtectInit(void) 3772 { 3773 /* 3774 * Initialize the globals. 3775 */ 3776 3777 /* The NT version. */ 3778 ULONG uMajor, uMinor, uBuild; 3779 PsGetVersion(&uMajor, &uMinor, &uBuild, NULL); 3780 g_uNtVerCombined = SUP_MAKE_NT_VER_COMBINED(uMajor, uMinor, uBuild, 0, 0); 3781 3782 /* Resolve methods we want but isn't available everywhere. */ 3783 UNICODE_STRING RoutineName; 3784 3785 RtlInitUnicodeString(&RoutineName, L"ObRegisterCallbacks"); 3786 g_pfnObRegisterCallbacks = (PFNOBREGISTERCALLBACKS)MmGetSystemRoutineAddress(&RoutineName); 3787 3788 RtlInitUnicodeString(&RoutineName, L"ObUnRegisterCallbacks"); 3789 g_pfnObUnRegisterCallbacks = (PFNOBUNREGISTERCALLBACKS)MmGetSystemRoutineAddress(&RoutineName); 3790 3791 RtlInitUnicodeString(&RoutineName, L"PsSetCreateProcessNotifyRoutineEx"); 3792 g_pfnPsSetCreateProcessNotifyRoutineEx = (PFNPSSETCREATEPROCESSNOTIFYROUTINEEX)MmGetSystemRoutineAddress(&RoutineName); 3793 3794 RtlInitUnicodeString(&RoutineName, L"PsReferenceProcessFilePointer"); 3795 g_pfnPsReferenceProcessFilePointer = (PFNPSREFERENCEPROCESSFILEPOINTER)MmGetSystemRoutineAddress(&RoutineName); 3796 3797 RtlInitUnicodeString(&RoutineName, L"PsIsProtectedProcessLight"); 3798 g_pfnPsIsProtectedProcessLight = (PFNPSISPROTECTEDPROCESSLIGHT)MmGetSystemRoutineAddress(&RoutineName); 3799 3800 RtlInitUnicodeString(&RoutineName, L"ZwQueryVirtualMemory"); /* Yes, using Zw version here. */ 3801 g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)MmGetSystemRoutineAddress(&RoutineName); 3802 if (!g_pfnNtQueryVirtualMemory && g_uNtVerCombined < SUP_NT_VER_VISTA) 3803 { 3804 /* XP & W2K3 doesn't have this function exported, so we've cooked up a 3805 few alternative in the assembly helper file that uses the code in 3806 ZwQueryVolumeInformationFile with a different eax value. */ 3807 # ifdef RT_ARCH_X86 3808 uint8_t const *pbCode = (uint8_t const *)(uintptr_t)ZwQueryVolumeInformationFile; 3809 if (*pbCode == 0xb8) /* mov eax, dword */ 3810 switch (*(uint32_t const *)&pbCode[1]) 3811 { 3812 case 0xb0: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xAF; break; /* just in case */ 3813 case 0xb1: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB0; break; /* just in case */ 3814 case 0xb2: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB1; break; /* just in case */ 3815 case 0xb3: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB2; break; /* XP SP3 */ 3816 case 0xb4: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB2; break; /* just in case */ 3817 case 0xb5: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB3; break; /* just in case */ 3818 case 0xb6: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB4; break; /* just in case */ 3819 case 0xb7: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB5; break; /* just in case */ 3820 case 0xb8: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB6; break; /* just in case */ 3821 case 0xb9: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB7; break; /* just in case */ 3822 case 0xba: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xB8; break; /* just in case */ 3823 case 0xbb: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBA; break; /* W2K3 R2 SP2 */ 3824 case 0xbc: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBB; break; /* just in case */ 3825 case 0xbd: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBC; break; /* just in case */ 3826 case 0xbe: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBD; break; /* just in case */ 3827 case 0xbf: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0xBE; break; /* just in case */ 3828 } 3829 # elif defined(RT_ARCH_AMD64) 3830 uint8_t const *pbCode = (uint8_t const *)(uintptr_t)ZwRequestWaitReplyPort; 3831 if ( pbCode[ 0] == 0x48 /* mov rax, rsp */ 3832 && pbCode[ 1] == 0x8b 3833 && pbCode[ 2] == 0xc4 3834 && pbCode[ 3] == 0xfa /* cli */ 3835 && pbCode[ 4] == 0x48 /* sub rsp, 10h */ 3836 && pbCode[ 5] == 0x83 3837 && pbCode[ 6] == 0xec 3838 && pbCode[ 7] == 0x10 3839 && pbCode[ 8] == 0x50 /* push rax */ 3840 && pbCode[ 9] == 0x9c /* pushfq */ 3841 && pbCode[10] == 0x6a /* push 10 */ 3842 && pbCode[11] == 0x10 3843 && pbCode[12] == 0x48 /* lea rax, [nt!KiServiceLinkage] */ 3844 && pbCode[13] == 0x8d 3845 && pbCode[14] == 0x05 3846 && pbCode[19] == 0x50 /* push rax */ 3847 && pbCode[20] == 0xb8 /* mov eax,1fh <- the syscall no. */ 3848 /*&& pbCode[21] == 0x1f*/ 3849 && pbCode[22] == 0x00 3850 && pbCode[23] == 0x00 3851 && pbCode[24] == 0x00 3852 && pbCode[25] == 0xe9 /* jmp KiServiceInternal */ 3853 ) 3854 { 3855 uint8_t const *pbKiServiceInternal = &pbCode[30] + *(int32_t const *)&pbCode[26]; 3856 uint8_t const *pbKiServiceLinkage = &pbCode[19] + *(int32_t const *)&pbCode[15]; 3857 if (*pbKiServiceLinkage == 0xc3) 3858 { 3859 g_pfnKiServiceInternal = (PFNRT)pbKiServiceInternal; 3860 g_pfnKiServiceLinkage = (PFNRT)pbKiServiceLinkage; 3861 switch (pbCode[21]) 3862 { 3863 case 0x1e: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x1F; break; 3864 case 0x1f: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x20; break; 3865 case 0x20: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x21; break; 3866 case 0x21: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x22; break; 3867 case 0x22: g_pfnNtQueryVirtualMemory = (PFNNTQUERYVIRTUALMEMORY)supdrvNtQueryVirtualMemory_0x23; break; 3868 } 3869 } 3870 } 3871 # endif 3872 } 3873 if (!g_pfnNtQueryVirtualMemory) 3874 { 3875 LogRel(("vboxdrv: Cannot locate ZwQueryVirtualMemory in ntoskrnl, nor were we able to cook up a replacement.\n")); 3876 return STATUS_PROCEDURE_NOT_FOUND; 3877 } 3878 3879 3880 /* The spinlock protecting our structures. */ 3881 int rc = RTSpinlockCreate(&g_hNtProtectLock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "NtProtectLock"); 3882 if (RT_FAILURE(rc)) 3883 return VBoxDrvNtErr2NtStatus(rc); 3884 g_NtProtectTree = NULL; 3885 3886 /* Image stuff + certificates. */ 3887 NTSTATUS rcNt; 3888 rc = supHardenedWinInitImageVerifier(NULL); 3889 if (RT_SUCCESS(rc)) 3890 { 3891 /* 3892 * Intercept process creation and termination. 3893 */ 3894 if (g_pfnPsSetCreateProcessNotifyRoutineEx) 3895 rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, FALSE /*fRemove*/); 3896 else 3897 rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, FALSE /*fRemove*/); 3898 if (NT_SUCCESS(rcNt)) 3899 { 3900 /* 3901 * Intercept process and thread handle creation calls. 3902 * The preferred method is only available on Vista SP1+. 3903 */ 3904 if (g_pfnObRegisterCallbacks && g_pfnObUnRegisterCallbacks) 3905 { 3906 static OB_OPERATION_REGISTRATION s_aObOperations[] = 3907 { 3908 { 3909 PsProcessType, 3910 OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE, 3911 supdrvNtProtectCallback_ProcessHandlePre, 3912 supdrvNtProtectCallback_ProcessHandlePost, 3913 }, 3914 { 3915 PsThreadType, 3916 OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE, 3917 supdrvNtProtectCallback_ThreadHandlePre, 3918 supdrvNtProtectCallback_ThreadHandlePost, 3919 }, 3920 }; 3921 static OB_CALLBACK_REGISTRATION s_ObCallbackReg = 3922 { 3923 /* .Version = */ OB_FLT_REGISTRATION_VERSION, 3924 /* .OperationRegistrationCount = */ RT_ELEMENTS(s_aObOperations), 3925 /* .Altitude.Length = */ 0, 3926 /* .Altitude.MaximumLength = */ 0, 3927 /* .Altitude.Buffer = */ NULL, 3928 /* .RegistrationContext = */ NULL, 3929 /* .OperationRegistration = */ &s_aObOperations[0] 3930 }; 3931 static WCHAR const *s_apwszAltitudes[] = /** @todo get a valid number */ 3932 { 3933 L"48596.98940", L"46935.19485", L"49739.39704", L"40334.74976", 3934 L"66667.98940", L"69888.19485", L"69889.39704", L"60364.74976", 3935 L"85780.98940", L"88978.19485", L"89939.39704", L"80320.74976", 3936 L"329879.98940", L"326787.19485", L"328915.39704", L"320314.74976", 3937 }; 3938 3939 rcNt = STATUS_FLT_INSTANCE_ALTITUDE_COLLISION; 3940 for (uint32_t i = 0; i < RT_ELEMENTS(s_apwszAltitudes) && rcNt == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION; i++) 3941 { 3942 s_ObCallbackReg.Altitude.Buffer = (WCHAR *)s_apwszAltitudes[i]; 3943 s_ObCallbackReg.Altitude.Length = (uint16_t)RTUtf16Len(s_apwszAltitudes[i]) * sizeof(WCHAR); 3944 s_ObCallbackReg.Altitude.MaximumLength = s_ObCallbackReg.Altitude.Length + sizeof(WCHAR); 3945 3946 rcNt = g_pfnObRegisterCallbacks(&s_ObCallbackReg, &g_pvObCallbacksCookie); 3947 if (NT_SUCCESS(rcNt)) 3948 { 3949 /* 3950 * Happy ending. 3951 */ 3952 return STATUS_SUCCESS; 3953 } 3954 } 3955 LogRel(("vboxdrv: ObRegisterCallbacks failed with rcNt=%#x\n", rcNt)); 3956 g_pvObCallbacksCookie = NULL; 3957 } 3958 else 3959 { 3960 /* 3961 * For the time being, we do not implement extra process 3962 * protection on pre-Vista-SP1 systems as they are lacking 3963 * necessary KPIs. XP is end of life, we do not wish to 3964 * spend more time on it, so we don't put up a fuss there. 3965 * Vista users without SP1 can install SP1 (or later), darn it, 3966 * so refuse to load. 3967 */ 3968 /** @todo Hack up an XP solution - will require hooking kernel APIs or doing bad 3969 * stuff to a couple of object types. */ 3970 # ifndef VBOX_WITH_VISTA_NO_SP 3971 if (g_uNtVerCombined >= SUP_NT_VER_VISTA) 3972 # else 3973 if (g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 6001, 0, 0)) 3974 # endif 3975 { 3976 DbgPrint("vboxdrv: ObRegisterCallbacks was not found. Please make sure you got the latest updates and service packs installed\n"); 3977 rcNt = STATUS_SXS_VERSION_CONFLICT; 3978 } 3979 else 3980 { 3981 Log(("vboxdrv: ObRegisterCallbacks was not found; ignored pre-Vista\n")); 3982 return rcNt = STATUS_SUCCESS; 3983 } 3984 g_pvObCallbacksCookie = NULL; 3985 } 3986 3987 /* 3988 * Drop process create/term notifications. 3989 */ 3990 if (g_pfnPsSetCreateProcessNotifyRoutineEx) 3991 g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/); 3992 else 3993 PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, TRUE /*fRemove*/); 3994 } 3995 else 3996 LogRel(("vboxdrv: PsSetCreateProcessNotifyRoutine%s failed with rcNt=%#x\n", 3997 g_pfnPsSetCreateProcessNotifyRoutineEx ? "Ex" : "", rcNt)); 3998 supHardenedWinTermImageVerifier(); 3999 } 4000 else 4001 rcNt = VBoxDrvNtErr2NtStatus(rc); 4002 4003 RTSpinlockDestroy(g_hNtProtectLock); 4004 g_NtProtectTree = NIL_RTSPINLOCK; 4005 return rcNt; 4006 } 4007 4008 #endif /* VBOX_WITH_HARDENING */ 4009 -
trunk/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm
r44528 r51770 5 5 6 6 ; 7 ; Copyright (C) 2006-201 0Oracle Corporation7 ; Copyright (C) 2006-2014 Oracle Corporation 8 8 ; 9 9 ; This file is part of VirtualBox Open Source Edition (OSE), as … … 45 45 %endif 46 46 47 48 %ifdef RT_ARCH_X86 49 ; 50 ; Faking up ZwQueryVirtualMemory on XP and W2K3 where it's not exported. 51 ; Using ZwQueryVolumeInformationFile as a helper. 52 ; 53 extern IMPNAME(ZwQueryVolumeInformationFile@20) 54 55 BEGINPROC supdrvNtQueryVirtualMemory_Xxx 56 %macro NtQueryVirtualMemorySyscall 1 57 GLOBALNAME supdrvNtQueryVirtualMemory_ %+ %1 58 mov eax, %1 59 jmp supdrvNtQueryVirtualMemory_Jump 60 %endm 61 NtQueryVirtualMemorySyscall 0xAF 62 NtQueryVirtualMemorySyscall 0xB0 63 NtQueryVirtualMemorySyscall 0xB1 64 NtQueryVirtualMemorySyscall 0xB2 65 NtQueryVirtualMemorySyscall 0xB3 66 NtQueryVirtualMemorySyscall 0xB4 67 NtQueryVirtualMemorySyscall 0xB5 68 NtQueryVirtualMemorySyscall 0xB6 69 NtQueryVirtualMemorySyscall 0xB7 70 NtQueryVirtualMemorySyscall 0xB8 71 NtQueryVirtualMemorySyscall 0xB9 72 NtQueryVirtualMemorySyscall 0xBA 73 NtQueryVirtualMemorySyscall 0xBB 74 NtQueryVirtualMemorySyscall 0xBC 75 NtQueryVirtualMemorySyscall 0xBD 76 NtQueryVirtualMemorySyscall 0xBE 77 78 supdrvNtQueryVirtualMemory_Jump: 79 mov edx, IMP2(ZwQueryVolumeInformationFile@20) 80 lea edx, [edx + 5] 81 jmp edx 82 ENDPROC supdrvNtQueryVirtualMemory_Xxx 83 84 %endif 85 86 %ifdef RT_ARCH_AMD64 87 ; 88 ; Faking up ZwQueryVirtualMemory on XP64 and W2K3-64 where it's not exported. 89 ; The C code locates and verifies the essentials in ZwRequestWaitReplyPort. 90 ; 91 extern NAME(g_pfnKiServiceLinkage) 92 extern NAME(g_pfnKiServiceInternal) 93 BEGINPROC supdrvNtQueryVirtualMemory_Xxx 94 %macro NtQueryVirtualMemorySyscall 1 95 GLOBALNAME supdrvNtQueryVirtualMemory_ %+ %1 96 mov eax, %1 97 jmp supdrvNtQueryVirtualMemory_Jump 98 %endm 99 100 NtQueryVirtualMemorySyscall 0x1F 101 NtQueryVirtualMemorySyscall 0x20 102 NtQueryVirtualMemorySyscall 0x21 103 NtQueryVirtualMemorySyscall 0x22 104 NtQueryVirtualMemorySyscall 0x23 105 106 supdrvNtQueryVirtualMemory_Jump: 107 cli 108 mov r10, rsp ; save call frame pointer. 109 mov r11, [NAME(g_pfnKiServiceLinkage) wrt rip] 110 push 0 111 push 0 112 push r10 ; call frame pointer (incoming rsp). 113 pushfq 114 push 10h 115 push r11 ; r11 = KiServiceLinkage (ret w/ unwind info) 116 jmp qword [NAME(g_pfnKiServiceInternal) wrt rip] 117 ENDPROC supdrvNtQueryVirtualMemory_Xxx 118 %endif 119 -
trunk/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp
r49213 r51770 31 31 #ifdef IN_SUP_HARDENED_R3 32 32 # undef DEBUG /* Warning: disables RT_STRICT */ 33 # undef LOG_DISABLED 33 34 # define LOG_DISABLED 34 35 /** @todo RTLOGREL_DISABLED */ … … 39 40 40 41 #define USE_NT_DEVICE_IO_CONTROL_FILE 41 #ifdef USE_NT_DEVICE_IO_CONTROL_FILE 42 # include <iprt/nt/nt-and-windows.h> 43 #else 44 # include <Windows.h> 45 #endif 42 #include <iprt/nt/nt-and-windows.h> 46 43 47 44 #include <VBox/sup.h> … … 55 52 #include "../SUPLibInternal.h" 56 53 #include "../SUPDrvIOC.h" 54 #ifdef VBOX_WITH_HARDENING 55 # include "win/SUPHardenedVerify-win.h" 56 #endif 57 57 58 58 … … 75 75 * Internal Functions * 76 76 *******************************************************************************/ 77 #ifndef IN_SUP_HARDENED_R3 77 78 static int suplibOsCreateService(void); 78 79 //unused: static int suplibOsUpdateService(void); … … 80 81 static int suplibOsStartService(void); 81 82 static int suplibOsStopService(void); 83 #endif 82 84 #ifdef USE_NT_DEVICE_IO_CONTROL_FILE 83 85 static int suplibConvertNtStatus(NTSTATUS rcNt); … … 87 89 88 90 89 90 91 91 int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted) 92 92 { 93 93 /* 94 * Nothing to do if pre-inited.94 * Almost nothing to do if pre-inited. 95 95 */ 96 96 if (fPreInited) 97 { 98 #if defined(VBOX_WITH_HARDENING) && !defined(IN_SUP_HARDENED_R3) 99 # ifdef IN_SUP_R3_STATIC 100 return VERR_NOT_SUPPORTED; 101 # else 102 supR3HardenedWinInitVersion(); 103 return supHardenedWinInitImageVerifier(NULL); 104 # endif 105 #else 97 106 return VINF_SUCCESS; 107 #endif 108 } 98 109 99 110 /* 100 111 * Try open the device. 101 112 */ 102 HANDLE hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR,103 GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,104 NULL,105 OPEN_EXISTING,106 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,107 NULL);108 if (hDevice == INVALID_HANDLE_VALUE)109 {110 113 #ifndef IN_SUP_HARDENED_R3 111 /* 112 * Try start the service and retry opening it. 113 */ 114 suplibOsStartService(); 115 116 hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR, 117 GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 118 NULL, 119 OPEN_EXISTING, 120 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 121 NULL); 122 if (hDevice == INVALID_HANDLE_VALUE) 123 #endif /* !IN_SUP_HARDENED_R3 */ 124 { 125 int rc = GetLastError(); 126 switch (rc) 114 uint32_t cTry = 0; 115 #endif 116 HANDLE hDevice; 117 for (;;) 118 { 119 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 120 121 static const WCHAR s_wszName[] = L"\\Device\\VBoxDrvU"; 122 UNICODE_STRING NtName; 123 NtName.Buffer = (PWSTR)s_wszName; 124 NtName.Length = sizeof(s_wszName) - sizeof(WCHAR) * (fUnrestricted ? 2 : 1); 125 NtName.MaximumLength = NtName.Length; 126 127 OBJECT_ATTRIBUTES ObjAttr; 128 InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/); 129 130 hDevice = RTNT_INVALID_HANDLE_VALUE; 131 132 NTSTATUS rcNt = NtCreateFile(&hDevice, 133 GENERIC_READ | GENERIC_WRITE, 134 &ObjAttr, 135 &Ios, 136 NULL /* Allocation Size*/, 137 FILE_ATTRIBUTE_NORMAL, 138 FILE_SHARE_READ | FILE_SHARE_WRITE, 139 FILE_OPEN, 140 FILE_NON_DIRECTORY_FILE, 141 NULL /*EaBuffer*/, 142 0 /*EaLength*/); 143 if (NT_SUCCESS(rcNt)) 144 rcNt = Ios.Status; 145 if (!NT_SUCCESS(rcNt)) 146 { 147 #ifndef IN_SUP_HARDENED_R3 148 /* 149 * Failed to open, try starting the service and reopen the device 150 * exactly once. 151 */ 152 if (cTry == 0 && !NT_SUCCESS(rcNt)) 153 { 154 cTry++; 155 suplibOsStartService(); 156 continue; 157 } 158 #endif 159 switch (rcNt) 127 160 { 128 161 /** @todo someone must test what is actually returned. */ 129 case ERROR_DEV_NOT_EXIST:130 case ERROR_DEVICE_NOT_CONNECTED:131 case ERROR_BAD_DEVICE:132 case ERROR_DEVICE_REMOVED:133 case ERROR_DEVICE_NOT_AVAILABLE:162 case STATUS_DEVICE_DOES_NOT_EXIST: 163 case STATUS_DEVICE_NOT_CONNECTED: 164 //case ERROR_BAD_DEVICE: 165 case STATUS_DEVICE_REMOVED: 166 //case ERROR_DEVICE_NOT_AVAILABLE: 134 167 return VERR_VM_DRIVER_LOAD_ERROR; 135 case ERROR_PATH_NOT_FOUND: 136 case ERROR_FILE_NOT_FOUND: 168 case STATUS_OBJECT_PATH_NOT_FOUND: 169 case STATUS_NO_SUCH_DEVICE: 170 case STATUS_NO_SUCH_FILE: 171 case STATUS_OBJECT_NAME_NOT_FOUND: 137 172 return VERR_VM_DRIVER_NOT_INSTALLED; 138 case ERROR_ACCESS_DENIED:139 case ERROR_SHARING_VIOLATION:173 case STATUS_ACCESS_DENIED: 174 case STATUS_SHARING_VIOLATION: 140 175 return VERR_VM_DRIVER_NOT_ACCESSIBLE; 176 case STATUS_UNSUCCESSFUL: 177 return VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0; 178 case STATUS_TRUST_FAILURE: 179 return VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1; 180 case STATUS_TOO_LATE: 181 return VERR_SUPDRV_HARDENING_EVIL_HANDLE; 141 182 default: 183 184 return rcNt; 142 185 return VERR_VM_DRIVER_OPEN_ERROR; 143 186 } 144 145 return -1 /** @todo define proper error codes for suplibOsInit failure. */; 146 } 187 } 188 break; 147 189 } 148 190 … … 154 196 return VINF_SUCCESS; 155 197 } 156 157 198 158 199 #ifndef IN_SUP_HARDENED_R3 … … 440 481 fRc = StartService(hService, 0, NULL); 441 482 DWORD LastError = GetLastError(); NOREF(LastError); 483 #ifndef DEBUG_bird 442 484 AssertMsg(fRc, ("StartService failed with LastError=%Rwa\n", LastError)); 485 #endif 443 486 } 444 487 … … 652 695 } 653 696 697 /* See VBoxDrvNtErr2NtStatus. */ 698 if (((uint32_t)rcNt & 0xffff0000) == UINT32_C(0xe9860000)) /** @todo defines for these? */ 699 return (int)((uint32_t)rcNt | UINT32_C(0xffff0000)); 700 654 701 /* Fall back on IPRT for the rest. */ 655 702 return RTErrConvertFromNtStatus(rcNt);
Note:
See TracChangeset
for help on using the changeset viewer.