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:26:11 GMT

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

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

    Description: 
Issue: EventLogAppender can corrupt the event log on Windows Vista and higher if the string
is longer than 31839 bytes.

The log4net EventLogAppender allows you to write up to 32000 bytes and there is a defect in
the .NET Framework that will let you write that much data in Windows Vista and higher (which
has a limit of 31839).

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. I've also written our own custom EventLogAppender that is able to work around
this issue.

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:
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;
}		

    
> 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: EventLogAppender can corrupt the event log on Windows Vista and higher if the
string is longer than 31839 bytes.
> The log4net EventLogAppender allows you to write up to 32000 bytes and there is a defect
in the .NET Framework that will let you write that much data in Windows Vista and higher (which
has a limit of 31839).
> 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. I've also written our own custom EventLogAppender that is able to work around
this issue.
> 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