[ https://issues.apache.org/jira/browse/LOG4NET-360?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Michael Cessna updated LOG4NET-360: ----------------------------------- Description: Issue: https://connect.microsoft.com/VisualStudio/feedback/details/770126/eventlog-writeentry-can-corrupt-the-event-log-because-of-invalid-argument-check-in-net-framework#tabs See the attachment that shows "$exception {"The event log file is corrupted"} System.Exception {System.ComponentModel.Win32Exception}" along with the stack after a call to EventLog.WriteEntry() under Windows 7 that used a message string that was 31,876 bytes long. The issue has been reported to Microsoft as well: https://connect.microsoft.com/VisualStudio/feedback/details/770126/eventlog-writeentry-can-corrupt-the-event-log-because-of-invalid-argument-check-in-net-framework#tabs The code below is my workaround for determining a max message length that will not corrupt the event log. private const int MaxEventLogMsgLength_PreVista = 32766; private const int MaxEventLogMsgLength_VistaOrHigher = 31839; /// <summary> /// Gets the maximum allowable size of event log message for the current operating system. /// </summary> /// <returns></returns> public static int GetMaxEventLogMessageSize() { // http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx // The 32766 documented max size is two bytes shy of 32K (I'm assuming 32766 may leave space for a two byte null // terminator of #0#0). The 32766 max length is what the .NET 4.0 source code checks for, but this is WRONG!... // strings with a length > 31839 on Windows Vista or higher can CORRUPT the event log! See: // System.Diagnostics.EventLogInternal.InternalWriteEvent() for the use of the 32766 max size. var maxEventMsgSize = MaxEventLogMsgLength_PreVista; // Windows Vista and higher if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6) { // See ReportEvent API: http://msdn.microsoft.com/en-us/library/aa363679(VS.85).aspx // ReportEvent's lpStrings parameter: "A pointer to a buffer containing an array of null-terminated strings that are // merged into the message before Event Viewer displays the string to the user. This parameter must be a valid pointer // (or NULL), even if wNumStrings is zero. Each string is limited to 31,839 characters." // Going beyond the size of 31839 will (at some point) corrupt the event log on Windows Vista or higher! It may succeed // for a while...but you will eventually run into the error: "System.ComponentModel.Win32Exception : A device attached to // the system is not functioning", and the event log will then be corrupt (I was able to corrupt an event log using a // length of 31877 on Windows 7). // The max size for Windows Vista or higher is documented here: http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx. // Going over this size may succeed a few times but the buffer will overrun and eventually corrupt the log (based on testing). // Log4net's own EventLogAppender will write up to 32000 bytes (0x7D00), which can corrupt the event log. // The maxEventMsgSize size is based on the max buffer size of the lpStrings parameter of the ReportEvent API. // The documented max size for EventLog.WriteEntry for Windows Vista and higher is 31839, but I'm leaving room for a // terminator of #0#0, as we cannot see the source of ReportEvent (though we could use an API monitor to examine the // buffer, given enough time). // TODO: Use an API monitor to examine how the ReportEvent API allocates a buffer for the event log message strings. const int terminatorLength = 2; // Safety for now. maxEventMsgSize = MaxEventLogMsgLength_VistaOrHigher - terminatorLength; } return maxEventMsgSize; } was: See the attachment that shows "$exception {"The event log file is corrupted"} System.Exception {System.ComponentModel.Win32Exception}" along with the stack after a call to EventLog.WriteEntry() under Windows 7 that used a message string that was 31,876 bytes long. The issue has been reported to Microsoft as well: https://connect.microsoft.com/VisualStudio/feedback/details/770126/eventlog-writeentry-can-corrupt-the-event-log-because-of-invalid-argument-check-in-net-framework#tabs The code below is my workaround for determining a max message length that will not corrupt the event log. private const int MaxEventLogMsgLength_PreVista = 32766; private const int MaxEventLogMsgLength_VistaOrHigher = 31839; /// <summary> /// Gets the maximum allowable size of event log message for the current operating system. /// </summary> /// <returns></returns> public static int GetMaxEventLogMessageSize() { // http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx // The 32766 documented max size is two bytes shy of 32K (I'm assuming 32766 may leave space for a two byte null // terminator of #0#0). The 32766 max length is what the .NET 4.0 source code checks for, but this is WRONG!... // strings with a length > 31839 on Windows Vista or higher can CORRUPT the event log! See: // System.Diagnostics.EventLogInternal.InternalWriteEvent() for the use of the 32766 max size. var maxEventMsgSize = MaxEventLogMsgLength_PreVista; // Windows Vista and higher if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6) { // See ReportEvent API: http://msdn.microsoft.com/en-us/library/aa363679(VS.85).aspx // ReportEvent's lpStrings parameter: "A pointer to a buffer containing an array of null-terminated strings that are // merged into the message before Event Viewer displays the string to the user. This parameter must be a valid pointer // (or NULL), even if wNumStrings is zero. Each string is limited to 31,839 characters." // Going beyond the size of 31839 will (at some point) corrupt the event log on Windows Vista or higher! It may succeed // for a while...but you will eventually run into the error: "System.ComponentModel.Win32Exception : A device attached to // the system is not functioning", and the event log will then be corrupt (I was able to corrupt an event log using a // length of 31877 on Windows 7). // The max size for Windows Vista or higher is documented here: http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx. // Going over this size may succeed a few times but the buffer will overrun and eventually corrupt the log (based on testing). // Log4net's own EventLogAppender will write up to 32000 bytes (0x7D00), which can corrupt the event log. // The maxEventMsgSize size is based on the max buffer size of the lpStrings parameter of the ReportEvent API. // The documented max size for EventLog.WriteEntry for Windows Vista and higher is 31839, but I'm leaving room for a // terminator of #0#0, as we cannot see the source of ReportEvent (though we could use an API monitor to examine the // buffer, given enough time). // TODO: Use an API monitor to examine how the ReportEvent API allocates a buffer for the event log message strings. const int terminatorLength = 2; // Safety for now. maxEventMsgSize = MaxEventLogMsgLength_VistaOrHigher - terminatorLength; } return maxEventMsgSize; } > EventLogAppender can corrupt the event log on Windows Vista and higher if the > string is longer than 31839 bytes > --------------------------------------------------------------------------------------------------------------- > > Key: LOG4NET-360 > URL: https://issues.apache.org/jira/browse/LOG4NET-360 > Project: Log4net > Issue Type: Bug > Components: Appenders > Affects Versions: 1.2.11 > Environment: Windows Vista or higher > Reporter: Michael Cessna > Priority: Blocker > Attachments: Event Log Corruption.txt > > > Issue: > https://connect.microsoft.com/VisualStudio/feedback/details/770126/eventlog-writeentry-can-corrupt-the-event-log-because-of-invalid-argument-check-in-net-framework#tabs > See the attachment that shows "$exception {"The event log file is > corrupted"} System.Exception {System.ComponentModel.Win32Exception}" > along with the stack after a call to EventLog.WriteEntry() under Windows 7 > that used a message string that was 31,876 bytes long. > The issue has been reported to Microsoft as well: > https://connect.microsoft.com/VisualStudio/feedback/details/770126/eventlog-writeentry-can-corrupt-the-event-log-because-of-invalid-argument-check-in-net-framework#tabs > The code below is my workaround for determining a max message length that > will not corrupt the event log. > private const int MaxEventLogMsgLength_PreVista = 32766; > private const int MaxEventLogMsgLength_VistaOrHigher = 31839; > /// <summary> > /// Gets the maximum allowable size of event log message for the current > operating system. > /// </summary> > /// <returns></returns> > public static int GetMaxEventLogMessageSize() > { > // http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx > > // The 32766 documented max size is two bytes shy of 32K (I'm assuming > 32766 may leave space for a two byte null > // terminator of #0#0). The 32766 max length is what the .NET 4.0 > source code checks for, but this is WRONG!... > // strings with a length > 31839 on Windows Vista or higher can CORRUPT > the event log! See: > // System.Diagnostics.EventLogInternal.InternalWriteEvent() for the use > of the 32766 max size. > var maxEventMsgSize = MaxEventLogMsgLength_PreVista; > // Windows Vista and higher > if (Environment.OSVersion.Platform == PlatformID.Win32NT && > Environment.OSVersion.Version.Major >= 6) > { > // See ReportEvent API: > http://msdn.microsoft.com/en-us/library/aa363679(VS.85).aspx > // ReportEvent's lpStrings parameter: "A pointer to a buffer > containing an array of null-terminated strings that are > // merged into the message before Event Viewer displays the > string to the user. This parameter must be a valid pointer > // (or NULL), even if wNumStrings is zero. Each string is > limited to 31,839 characters." > // Going beyond the size of 31839 will (at some point) corrupt > the event log on Windows Vista or higher! It may succeed > // for a while...but you will eventually run into the error: > "System.ComponentModel.Win32Exception : A device attached to > // the system is not functioning", and the event log will then > be corrupt (I was able to corrupt an event log using a > // length of 31877 on Windows 7). > // The max size for Windows Vista or higher is documented here: > http://msdn.microsoft.com/en-us/library/xzwc042w(v=vs.100).aspx. > // Going over this size may succeed a few times but the buffer > will overrun and eventually corrupt the log (based on testing). > // Log4net's own EventLogAppender will write up to 32000 bytes > (0x7D00), which can corrupt the event log. > // The maxEventMsgSize size is based on the max buffer size of > the lpStrings parameter of the ReportEvent API. > // The documented max size for EventLog.WriteEntry for Windows > Vista and higher is 31839, but I'm leaving room for a > // terminator of #0#0, as we cannot see the source of > ReportEvent (though we could use an API monitor to examine the > // buffer, given enough time). > // TODO: Use an API monitor to examine how the ReportEvent API > allocates a buffer for the event log message strings. > const int terminatorLength = 2; // Safety for now. > maxEventMsgSize = MaxEventLogMsgLength_VistaOrHigher - > terminatorLength; > } > return maxEventMsgSize; > } -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira