logging-log4net-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Michael Cessna (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (LOG4NET-360) EventLogAppender can corrupt the event log on Windows Vista and higher if the string is longer than 31839 bytes
Date Mon, 05 Nov 2012 23:20:13 GMT

     [ https://issues.apache.org/jira/browse/LOG4NET-360?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Michael Cessna updated LOG4NET-360:
-----------------------------------

    Description: 
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:
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
>
>
> 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

Mime
View raw message