Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
5.4 KiB

  1. /***
  2. *seclocf.c - Report /GS security check failure, local system CRT version
  3. *
  4. * Copyright (c) 2000-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Define function used to report a security check failure. This
  8. * version is only used when linking against the system CRT DLL,
  9. * msvcrt.dll (or msvcrtd.dll). If that DLL does not export the global
  10. * failure handler __security_error_handler, then a default local
  11. * handler is used instead.
  12. *
  13. * This version does not use any other CRT functions, so it can be used
  14. * to compile code /GS which does not want to use the CRT.
  15. *
  16. * Entrypoints:
  17. * __local_security_error_handler
  18. *
  19. *Revision History:
  20. * 01-24-00 PML Created.
  21. * 08-30-00 PML Rename handlers, add extra parameters. Extensively
  22. * rework, moving the GetProcAddress of
  23. * __security_error_handler from seccook.c to here.
  24. * 03-28-01 PML Protect against GetModuleFileName overflow (vs7#231284)
  25. *
  26. *******************************************************************************/
  27. #if defined(_SYSCRT) && defined(CRTDLL)
  28. #include <windows.h>
  29. #include <stdlib.h>
  30. /*
  31. * Default messagebox string components
  32. */
  33. #define PROGINTRO "Program: "
  34. #define DOTDOTDOT "..."
  35. #define BOXINTRO_0 "Unknown security failure detected!"
  36. #define MSGTEXT_0 \
  37. "A security error of unknown cause has been detected which has\n" \
  38. "corrupted the program's internal state. The program cannot safely\n" \
  39. "continue execution and must now be terminated.\n"
  40. #define BOXINTRO_1 "Buffer overrun detected!"
  41. #define MSGTEXT_1 \
  42. "A buffer overrun has been detected which has corrupted the program's\n" \
  43. "internal state. The program cannot safely continue execution and must\n"\
  44. "now be terminated.\n"
  45. #define MAXLINELEN 60 /* max length for line in message box */
  46. /***
  47. *__local_security_error_handler() - Report security error
  48. *
  49. *Purpose:
  50. * A /GS security error has been detected, and the global failure handler
  51. * is not available from msvcrt.dll. Pop up a message box and terminate
  52. * the program.
  53. *
  54. *Entry:
  55. * int code - security failure code
  56. * void *data - code-specific data
  57. *
  58. *Exit:
  59. * Calls ExitProcess.
  60. *
  61. *Exceptions:
  62. *
  63. *******************************************************************************/
  64. void __cdecl __local_security_error_handler(
  65. int code,
  66. void *data)
  67. {
  68. char progname[MAX_PATH + 1];
  69. char * pch;
  70. char * outmsg;
  71. char * boxintro;
  72. char * msgtext;
  73. size_t subtextlen;
  74. HANDLE hCRT;
  75. _secerr_handler_func pfnSecErrorHandler;
  76. HANDLE hUser32;
  77. int (APIENTRY *pfnMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
  78. /*
  79. * Check if the system CRT DLL implements the process-wide security
  80. * failure handler, and use it instead if available.
  81. */
  82. #ifdef _DEBUG
  83. hCRT = GetModuleHandle("msvcrtd.dll");
  84. #else
  85. hCRT = GetModuleHandle("msvcrt.dll");
  86. #endif
  87. if (hCRT != NULL) {
  88. pfnSecErrorHandler = (_secerr_handler_func)
  89. GetProcAddress(hCRT, "__security_error_handler");
  90. if (pfnSecErrorHandler != NULL) {
  91. pfnSecErrorHandler(code, data);
  92. ExitProcess(3);
  93. }
  94. }
  95. /*
  96. * DLL-resident handler not available. Use a local version that just
  97. * pops up a message box.
  98. */
  99. switch (code) {
  100. default:
  101. /*
  102. * Unknown failure code, which probably means an older CRT is
  103. * being used with a newer compiler.
  104. */
  105. boxintro = BOXINTRO_0;
  106. msgtext = MSGTEXT_0;
  107. subtextlen = sizeof(BOXINTRO_0) + sizeof(MSGTEXT_0);
  108. break;
  109. case _SECERR_BUFFER_OVERRUN:
  110. /*
  111. * Buffer overrun detected which may have overwritten a return
  112. * address.
  113. */
  114. boxintro = BOXINTRO_1;
  115. msgtext = MSGTEXT_1;
  116. subtextlen = sizeof(BOXINTRO_1) + sizeof(MSGTEXT_1);
  117. break;
  118. }
  119. progname[MAX_PATH] = '\0';
  120. if (!GetModuleFileName(NULL, progname, MAX_PATH))
  121. lstrcpy(progname, "<program name unknown>");
  122. pch = progname;
  123. /* sizeof(PROGINTRO) includes the NULL terminator */
  124. if (sizeof(PROGINTRO) + lstrlen(progname) + 1 > MAXLINELEN)
  125. {
  126. pch += (sizeof(PROGINTRO) + lstrlen(progname) + 1) - MAXLINELEN;
  127. CopyMemory(pch, DOTDOTDOT, sizeof(DOTDOTDOT) - 1);
  128. }
  129. outmsg = (char *)_alloca(subtextlen - 1 + 2
  130. + sizeof(PROGINTRO) - 1
  131. + lstrlen(pch)
  132. + 2);
  133. lstrcpy(outmsg, boxintro);
  134. lstrcat(outmsg, "\n\n");
  135. lstrcat(outmsg, PROGINTRO);
  136. lstrcat(outmsg, pch);
  137. lstrcat(outmsg, "\n\n");
  138. lstrcat(outmsg, msgtext);
  139. hUser32 = LoadLibrary("user32.dll");
  140. if (hUser32 != NULL) {
  141. pfnMessageBoxA = (int (APIENTRY *)(HWND, LPCSTR, LPCSTR, UINT))
  142. GetProcAddress(hUser32, "MessageBoxA");
  143. if (pfnMessageBoxA != NULL) {
  144. pfnMessageBoxA(
  145. NULL,
  146. outmsg,
  147. "Microsoft Visual C++ Runtime Library",
  148. MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
  149. }
  150. FreeLibrary(hUser32);
  151. }
  152. ExitProcess(3);
  153. }
  154. #endif /* defined(_SYSCRT) && defined(CRTDLL) */