fix(protocol): harden STATUS_ERROR_DETAIL receive path
Address review/security findings in the 2.21.0 error-detail feature: - Keepalive drain no longer erases the terminal detail: capture/clear is skipped for STATUS_KEEPALIVE so the reason the peer just sent survives the owed keepalive replies. - Replace the capture path with a dedicated protocol_receive_error_detail: the declared length is validated against MAX_ERROR_DETAIL_BYTES before any allocation, over-cap bodies are drained through a fixed scratch buffer (so the stream never desyncs), in-cap bodies read straight into the thread-local detail buffer, and session->max_alloc is never raised. Lengths beyond MAX_STRING_SIZE are treated as a fatal framing error. - The detail body now honors the caller's deadline (timed/keepalive paths) and polls the abort callback between drain chunks. - Escape peer-controlled detail text with output_escape before logging it in client_send.c and config.c. - Clear io_error_detail in io_set_fds so a new connection on the same thread cannot inherit a stale reason. - Add unit tests for the keepalive-survival, over-cap drain, absurd-length fatal framing, and deadline-clamped body read cases.
This commit is contained in:
@@ -53,10 +53,15 @@
|
||||
client-side context; a bare STATUS_ERROR still logs the context alone. */
|
||||
static void log_server_rejection(const char* context) {
|
||||
const char* detail = protocol_last_error();
|
||||
if (detail && detail[0] != '\0')
|
||||
log_message(LOG_LEVEL_ERROR, "%s: %s", context, detail);
|
||||
else
|
||||
if (detail && detail[0] != '\0') {
|
||||
/* The detail is peer-controlled: escape it so terminal/log-format
|
||||
* metacharacters cannot be injected into the client's output. */
|
||||
char* escaped = output_escape(detail, log_get_8_bit_output());
|
||||
log_message(LOG_LEVEL_ERROR, "%s: %s", context, escaped ? escaped : "<allocation failed>");
|
||||
free(escaped);
|
||||
} else {
|
||||
log_message(LOG_LEVEL_ERROR, "%s", context);
|
||||
}
|
||||
}
|
||||
|
||||
/* Forward declaration for progress-reporting thread used in multithreaded send. */
|
||||
|
||||
Reference in New Issue
Block a user