From 73b5d0a9b9ace89edcee30d9d83eb16c27c6f9b2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Nov 2022 09:27:53 +0100 Subject: [PATCH] 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 --- NEWS | 2 ++ src/system/Error.hxx | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d3e2ed88a..44183827a 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ ver 0.23.11 (not yet released) * macOS: fix build failure "no archive members specified" +* Windows + - fix crash bug (stack buffer overflow) after I/O errors * Android/Windows - update OpenSSL to 3.0.7 diff --git a/src/system/Error.hxx b/src/system/Error.hxx index aa017966b..b6b5c1fc1 100644 --- a/src/system/Error.hxx +++ b/src/system/Error.hxx @@ -70,8 +70,11 @@ FormatLastError(DWORD code, const char *fmt, Args&&... args) noexcept { char buffer[512]; 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)...); + if (length >= max_prefix) + length = max_prefix - 1; char *p = buffer + length; *p++ = ':'; *p++ = ' ';