[ 
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

Reply via email to