system/Error: truncate the snprintf() return value

snprintf() does not return the (truncated) length actually written,
but the length that would be needed if the buffer were large enough.
This API usage mistake in FormatLastError() can lead to overflow of
the stack buffer, crashing the process (Windows only).

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1676
This commit is contained in:
Max Kellermann 2022-11-28 09:27:53 +01:00
parent c2d0f35e7a
commit 73b5d0a9b9
2 changed files with 6 additions and 1 deletions

2
NEWS
View File

@ -1,5 +1,7 @@
ver 0.23.11 (not yet released) ver 0.23.11 (not yet released)
* macOS: fix build failure "no archive members specified" * macOS: fix build failure "no archive members specified"
* Windows
- fix crash bug (stack buffer overflow) after I/O errors
* Android/Windows * Android/Windows
- update OpenSSL to 3.0.7 - update OpenSSL to 3.0.7

View File

@ -70,8 +70,11 @@ FormatLastError(DWORD code, const char *fmt, Args&&... args) noexcept
{ {
char buffer[512]; char buffer[512];
const auto end = buffer + sizeof(buffer); const auto end = buffer + sizeof(buffer);
size_t length = snprintf(buffer, sizeof(buffer) - 128, constexpr std::size_t max_prefix = sizeof(buffer) - 128;
size_t length = snprintf(buffer, max_prefix,
fmt, std::forward<Args>(args)...); fmt, std::forward<Args>(args)...);
if (length >= max_prefix)
length = max_prefix - 1;
char *p = buffer + length; char *p = buffer + length;
*p++ = ':'; *p++ = ':';
*p++ = ' '; *p++ = ' ';