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.

200 lines
5.8 KiB

  1. /***
  2. *secfail.c - Report a /GS security check failure
  3. *
  4. * Copyright (c) 2000-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Define function used to report a security check failure, along with a
  8. * routine for registering a new handler.
  9. *
  10. * Entrypoints:
  11. * __security_error_handler
  12. * _set_security_error_handler
  13. *
  14. * NOTE: The ATLMINCRT library includes a version of this file. If any
  15. * changes are made here, they should be duplicated in the ATL version.
  16. *
  17. *Revision History:
  18. * 01-24-00 PML Created.
  19. * 08-09-00 PML Never return from failure reporting.
  20. * 08-29-00 PML Rename handlers, add extra parameters
  21. * 03-28-01 PML Protect against GetModuleFileName overflow (vs7#231284)
  22. *
  23. *******************************************************************************/
  24. #include <cruntime.h>
  25. #include <internal.h>
  26. #include <windows.h>
  27. #include <stdlib.h>
  28. #include <awint.h>
  29. #include <dbgint.h>
  30. /*
  31. * User-registered failure reporting routine.
  32. */
  33. static _secerr_handler_func user_handler;
  34. /*
  35. * Default messagebox string components
  36. */
  37. #define PROGINTRO "Program: "
  38. #define DOTDOTDOT "..."
  39. #define BOXINTRO_0 "Unknown security failure detected!"
  40. #define MSGTEXT_0 \
  41. "A security error of unknown cause has been detected which has\n" \
  42. "corrupted the program's internal state. The program cannot safely\n" \
  43. "continue execution and must now be terminated.\n"
  44. #define BOXINTRO_1 "Buffer overrun detected!"
  45. #define MSGTEXT_1 \
  46. "A buffer overrun has been detected which has corrupted the program's\n" \
  47. "internal state. The program cannot safely continue execution and must\n"\
  48. "now be terminated.\n"
  49. #define MAXLINELEN 60 /* max length for line in message box */
  50. /***
  51. *__security_error_handler() - Report security error.
  52. *
  53. *Purpose:
  54. * A /GS security error has been detected. If a user-registered failure
  55. * reporting function is available, call it, otherwise bring up a default
  56. * message box describing the problem and terminate the program.
  57. *
  58. *Entry:
  59. * int code - security failure code
  60. * void *data - code-specific data
  61. *
  62. *Exit:
  63. * Does not return.
  64. *
  65. *Exceptions:
  66. *
  67. *******************************************************************************/
  68. void __cdecl __security_error_handler(
  69. int code,
  70. void *data)
  71. {
  72. /* Use user-registered handler if available. */
  73. if (user_handler != NULL) {
  74. __try {
  75. user_handler(code, data);
  76. }
  77. __except (EXCEPTION_EXECUTE_HANDLER) {
  78. /*
  79. * If user handler raises an exception, capture it and terminate
  80. * the program, since the EH stack may be corrupted above this
  81. * point.
  82. */
  83. }
  84. }
  85. else {
  86. char progname[MAX_PATH + 1];
  87. char * pch;
  88. char * outmsg;
  89. char * boxintro;
  90. char * msgtext;
  91. size_t subtextlen;
  92. switch (code) {
  93. default:
  94. /*
  95. * Unknown failure code, which probably means an older CRT DLL is
  96. * being used with a newer compiler.
  97. */
  98. boxintro = BOXINTRO_0;
  99. msgtext = MSGTEXT_0;
  100. subtextlen = sizeof(BOXINTRO_0) + sizeof(MSGTEXT_0);
  101. break;
  102. case _SECERR_BUFFER_OVERRUN:
  103. /*
  104. * Buffer overrun detected which may have overwritten a return
  105. * address.
  106. */
  107. boxintro = BOXINTRO_1;
  108. msgtext = MSGTEXT_1;
  109. subtextlen = sizeof(BOXINTRO_1) + sizeof(MSGTEXT_1);
  110. break;
  111. }
  112. /*
  113. * In debug CRT, report error with ability to call the debugger.
  114. */
  115. _RPT0(_CRT_ERROR, msgtext);
  116. progname[MAX_PATH] = '\0';
  117. if (!GetModuleFileName(NULL, progname, MAX_PATH))
  118. strcpy(progname, "<program name unknown>");
  119. pch = progname;
  120. /* sizeof(PROGINTRO) includes the NULL terminator */
  121. if (sizeof(PROGINTRO) + strlen(progname) + 1 > MAXLINELEN)
  122. {
  123. pch += (sizeof(PROGINTRO) + strlen(progname) + 1) - MAXLINELEN;
  124. strncpy(pch, DOTDOTDOT, sizeof(DOTDOTDOT) - 1);
  125. }
  126. outmsg = (char *)_alloca(subtextlen - 1 + 2
  127. + sizeof(PROGINTRO) - 1
  128. + strlen(pch) + 2);
  129. strcpy(outmsg, boxintro);
  130. strcat(outmsg, "\n\n");
  131. strcat(outmsg, PROGINTRO);
  132. strcat(outmsg, pch);
  133. strcat(outmsg, "\n\n");
  134. strcat(outmsg, msgtext);
  135. __crtMessageBoxA(
  136. outmsg,
  137. "Microsoft Visual C++ Runtime Library",
  138. MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
  139. }
  140. _exit(3);
  141. }
  142. /***
  143. *_set_security_error_handler(handler) - Register user handler
  144. *
  145. *Purpose:
  146. * Register a user failure reporting function.
  147. *
  148. *Entry:
  149. * _secerr_handler_func handler - the user handler
  150. *
  151. *Exit:
  152. * Returns the previous user handler
  153. *
  154. *Exceptions:
  155. *
  156. *******************************************************************************/
  157. _secerr_handler_func __cdecl _set_security_error_handler(
  158. _secerr_handler_func handler)
  159. {
  160. _secerr_handler_func old_handler;
  161. old_handler = user_handler;
  162. user_handler = handler;
  163. return old_handler;
  164. }
  165. /* TEMPORARY - old handler name, to be removed when tools are updated. */
  166. void __cdecl __buffer_overrun()
  167. {
  168. __security_error_handler(_SECERR_BUFFER_OVERRUN, NULL);
  169. }
  170. /* TEMPORARY - old handler name, to be removed when tools are updated. */
  171. _secerr_handler_func __cdecl __set_buffer_overrun_handler(
  172. _secerr_handler_func handler)
  173. {
  174. return _set_security_error_handler(handler);
  175. }