Log4net
  1. Log4net
  2. LOG4NET-360

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

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.11
    • Fix Version/s: 1.2.12
    • Component/s: Appenders
    • Labels:
      None
    • Environment:
      Windows Vista or higher

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

      1. Event Log Corruption.txt
        33 kB
        Michael Cessna
      2. EventLogAppender.cs.patch
        4 kB
        Dominik Psenner

        Issue Links

          Activity

          Hide
          Michael Cessna added a comment -

          This file shows the stack from an exception that was the result of a System.ComponentModel.Win32Exception with the message "The event log file is corrupted" after calling EventLog.WriteEntry() with a string 31,876 bytes long under Windows 7. Note: The error won't happen all of the time, but corruption will eventually occur.

          Show
          Michael Cessna added a comment - This file shows the stack from an exception that was the result of a System.ComponentModel.Win32Exception with the message "The event log file is corrupted" after calling EventLog.WriteEntry() with a string 31,876 bytes long under Windows 7. Note: The error won't happen all of the time, but corruption will eventually occur.
          Hide
          Dominik Psenner added a comment -

          Would you please provide a patch that I can review and eventually apply to the latest log4net trunk?

          Show
          Dominik Psenner added a comment - Would you please provide a patch that I can review and eventually apply to the latest log4net trunk?
          Hide
          Dominik Psenner added a comment - - edited

          I had a bit spare time and wrote down a patch. Please review it and test it together with the latest log4net trunk and post back if this resolves the issue.

          Show
          Dominik Psenner added a comment - - edited I had a bit spare time and wrote down a patch. Please review it and test it together with the latest log4net trunk and post back if this resolves the issue.
          Hide
          Michael Cessna added a comment -

          Yes, those edits look correct to me.

          Thanks

          Show
          Michael Cessna added a comment - Yes, those edits look correct to me. Thanks
          Hide
          Dominik Psenner added a comment -

          Commited patch as revision: 1416843

          Thanks for reviewing. As final step I would like that you test the newest log4net trunk to see if the patch does what it should and feedback the results. If it does we can resolve the issue.

          Show
          Dominik Psenner added a comment - Commited patch as revision: 1416843 Thanks for reviewing. As final step I would like that you test the newest log4net trunk to see if the patch does what it should and feedback the results. If it does we can resolve the issue.
          Hide
          Dominik Psenner added a comment -

          Due to no response I'm closing the issue now. Feel free to reopen it if you are not satisfied with the solution.

          Show
          Dominik Psenner added a comment - Due to no response I'm closing the issue now. Feel free to reopen it if you are not satisfied with the solution.

            People

            • Assignee:
              Dominik Psenner
              Reporter:
              Michael Cessna
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development