Skip to content

Commit 56e66fa

Browse files
Tatiana Azundris Nuernbergdahlerlend
authored andcommitted
Bug#32890918: Writing the Windows EventLog would occasionally fail
When converting the message to be logged to UCS-2 for Windows, the conversion routine could read beyond the end of the input string. Patch prevents this, adds comments to better explain the idiosyncrasies of our Windows logging, and renames variables to hopefully prevent uncertainty in the future. This patch comes with a big thank you to Shane Bester for dumps and other helpful files when the issue was elusive on my machine, and to Daniel Blanchard who went above and beyond creating a much optimized proof once I had a patch. Change-Id: Id28d09dcc5a51caf67d966034d485d28eed5c84e
1 parent 44eda7e commit 56e66fa

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

mysys/my_syslog.cc

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,31 @@ extern CHARSET_INFO my_charset_utf16le_bin;
5252
#endif
5353

5454
#ifdef _WIN32
55+
/**
56+
Windows EventLog messages
57+
58+
See sql/message.mc for the defined messages on Windows
59+
(and on how to add/modify messages).
60+
61+
Presently, only one message is used: message 100 (MSG_DEFAULT)
62+
is a template "%1" into which we insert the message my_syslog()
63+
is given.
64+
65+
0x[C][000][0064] -- 32 bits, left to right:
66+
67+
0xC:
68+
2:Severity (0x3 == Error) (0xC>>2)
69+
1:Custom or System (0x0 == System) ((0xC>>1) & 1)
70+
1:Rsrvd (0x0) (0xC & 1)
71+
72+
0x000:
73+
12:Facility (0x000 == FACILITY_NULL)
74+
75+
0x0064
76+
16:Code (0x0064 == 100)
77+
*/
5578
#define MSG_DEFAULT 0xC0000064L
79+
5680
static HANDLE hEventLog = NULL; // global
5781
#endif
5882

@@ -63,7 +87,7 @@ static HANDLE hEventLog = NULL; // global
6387
6488
@param cs Character set info of the message string
6589
@param level Log level
66-
@param msg Message to be logged
90+
@param msg Message to be logged (C-string)
6791
6892
@return
6993
0 Success
@@ -75,14 +99,21 @@ int my_syslog(const CHARSET_INFO *cs MY_ATTRIBUTE((unused)),
7599
int _level = EVENTLOG_INFORMATION_TYPE;
76100
wchar_t buff[MAX_SYSLOG_MESSAGE_SIZE];
77101
wchar_t *u16buf = NULL;
78-
size_t nchars;
79-
uint dummy_errors;
102+
size_t msg_len; // bytes (not wide-chars) in input
103+
size_t nbytes; // bytes (not wide-chars) in output
104+
uint dummy_errors; // number of conversion errors
80105

81106
DBUG_TRACE;
82107

108+
if ((msg == nullptr) || ((msg_len = strlen(msg)) == 0)) return 0;
109+
110+
// limit input to buffer size
111+
if (msg_len >= MAX_SYSLOG_MESSAGE_SIZE) msg_len = MAX_SYSLOG_MESSAGE_SIZE - 1;
112+
83113
switch (level) {
84-
case INFORMATION_LEVEL:
85114
case SYSTEM_LEVEL:
115+
// fall-through. consider EVENTLOG_SUCCESS.
116+
case INFORMATION_LEVEL:
86117
_level = EVENTLOG_INFORMATION_TYPE;
87118
break;
88119
case WARNING_LEVEL:
@@ -96,16 +127,24 @@ int my_syslog(const CHARSET_INFO *cs MY_ATTRIBUTE((unused)),
96127
}
97128

98129
if (hEventLog) {
99-
nchars = my_convert((char *)buff, sizeof(buff) - sizeof(buff[0]),
100-
&my_charset_utf16le_bin, msg, MAX_SYSLOG_MESSAGE_SIZE,
101-
cs, &dummy_errors);
130+
nbytes =
131+
my_convert((char *)buff, sizeof(buff) - sizeof(buff[0]),
132+
&my_charset_utf16le_bin, msg, msg_len, cs, &dummy_errors);
102133

103134
// terminate it with NULL
104-
buff[nchars / sizeof(wchar_t)] = L'\0';
135+
buff[nbytes / sizeof(wchar_t)] = L'\0';
105136
u16buf = buff;
106137

107-
if (!ReportEventW(hEventLog, _level, 0, MSG_DEFAULT, NULL, 1, 0,
108-
(LPCWSTR *)&u16buf, NULL))
138+
// Fetch mysqld's Windows default message, insert u16buf, log the result.
139+
if (!ReportEventW(hEventLog,
140+
_level, // severity
141+
0, // app-defined event category
142+
MSG_DEFAULT, // event ID / message ID (see above)
143+
NULL, // security identifier
144+
1, // number of strings in u16buf
145+
0, // number of bytes in raw data
146+
(LPCWSTR *)&u16buf, // 0-terminated strings
147+
NULL)) // raw (binary data)
109148
goto err;
110149
}
111150

@@ -122,6 +161,8 @@ int my_syslog(const CHARSET_INFO *cs MY_ATTRIBUTE((unused)),
122161

123162
DBUG_TRACE;
124163

164+
if ((msg == nullptr) || (*msg == '\0')) return 0;
165+
125166
switch (level) {
126167
case INFORMATION_LEVEL:
127168
case SYSTEM_LEVEL:

sql/server_component/log_builtins.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
6666

6767
extern CHARSET_INFO my_charset_utf16le_bin; // used in Windows EventLog
6868
static HANDLE hEventLog = NULL; // global
69-
#define MSG_DEFAULT 0xC0000064L
7069
#endif
7170

7271
PSI_memory_key key_memory_log_error_loaded_services;

0 commit comments

Comments
 (0)