.globl _KiUserExceptionDispatcher@8\r
_KiUserExceptionDispatcher@8:\r
\r
- /* Clear direction flag */\r
+ /* clear the direct flag \r
+ * text from bug 2279\r
+ * if it not clear it means that if an exception occurs while\r
+ * the direction flag is set (typically inside memmove), the \r
+ * exception handlers will be called with the direction flag still\r
+ * set. The Windows x86-32 and x86-64 ABI requires that the \r
+ * direction flag be Calling memset() with a compile-time constant \r
+ * size on both GCC and MSVC will result in inlining a "rep stosd" \r
+ * instruction. Because of the ABI, they will assume that the \r
+ * direction flag is clear and not emit a "cld" instruction. \r
+ * Using memset() in an exception handler therefore will \r
+ * corrupt memory if the exception occurred during a reverse copy \r
+ * such as a forward overlapping memmove().\r
+ *\r
+ * For reliability and ease of debugging, please add "cld" to the beginning of\r
+ * KiUserExceptionDispatcher. Note that the same will be true of x86-64 whenever\r
+ * that happens. This does not affect continuing execution; the CONTEXT of the\r
+ * exception has the direction flag set and will be restored upon NtContinue. \r
+ * KiUserApcDispatcher and KiUserCallbackDispatcher need to be evaluated for this\r
+ * issue.\r
+ */\r
+ \r
cld\r
\r
/* Save the Context and Exception Records */\r
mov ecx, [esp+4]\r
mov ebx, [esp]\r
\r
+ /* Call the vectored exception handler */\r
+ push ecx\r
+ push ebx\r
+ call _RtlpExecuteVectoredExceptionHandlers@8\r
+\r
+ /* Check for success */\r
+ or al, al\r
+ jnz ContinueExecution\r
+\r
/* Dispatch the exception */\r
sub esp, 8\r
call _RtlDispatchException@8\r
or al, al\r
jz RaiseException\r
\r
+ContinueExecution:\r
/* Pop off the records */\r
pop ebx\r
pop ecx\r