Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: stunnel-5.72-8.el10 ------ Summary: Stack-based Out-of-Bounds Read/Write in `s_vlog` via `vsnprintf` Misuse: an oversized attacker-controlled log message can make `s_vlog` index past its 1024-byte stack buffer during newline stripping, causing an out-of-bounds stack read and a possible out-of-bounds write that can destabilize the process. Requirements to exploit: A remote attacker needs network access to a `stunnel-5.72-8.el10` service configured for server-side IMAP protocol negotiation (`protocol = imap`) and must be able to send an unexpected IMAP command line longer than 1024 bytes but below the `fd_getline` 64KB guard. The demonstrated logging path emits at `LOG_ERR`, which is commonly enabled with the default `debug = notice` setting. Component affected: `stunnel-5.72-8.el10`, specifically `src/log.c` in `s_vlog`, with a demonstrated remote trigger path through `src/protocol.c` `imap_server_middle` and `src/network.c` `fd_getline` Version affected: `stunnel-5.72-8.el10` Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The demonstrated trigger is over the network by sending an oversized IMAP command to a reachable stunnel service in the affected protocol mode. AC:L - No race or unusual precondition is required beyond the affected configuration; a long unexpected command line is sufficient. PR:N - The demonstrated path does not require prior authentication. UI:N - No user interaction is required once the service is exposed. S:U - The invalid memory access occurs within the stunnel process. C:N - The available evidence shows an out-of-bounds read used for newline checking, but does not establish disclosure of memory contents to the attacker. I:N - A possible out-of-bounds write exists, but the report does not establish a reliable or attacker-controlled integrity impact. A:H - The invalid stack access can abort or destabilize the affected process, and repeated unauthenticated requests can be used to deny service in affected configurations. Impact: Moderate. Based on Red Hat's severity guidance, the currently supported impact is a remotely triggerable denial-of-service condition in specific protocol configurations rather than a broadly reachable default-path failure or a demonstrated confidentiality, integrity, or code-execution compromise. That makes the issue more constrained than a typical `Important` remote DoS and better fits `Moderate`. Embargo: no Reason: The demonstrated impact is denial of service in a configuration-dependent protocol path, with no established privilege escalation or code execution. Exposure can also be reduced operationally by disabling or restricting the affected protocol mode until a fix is shipped. Acknowledgement: Aisle Research Vulnerability Details: In `src/log.c`, `s_vlog` measures the formatted length, caps that length at 1024 for stack allocation, and then overwrites `len` with the return value from the second `vsnprintf` call. Because `vsnprintf` returns the full would-have-been output length, `len` can again exceed the allocated buffer size before the newline-stripping loop runs: ```c va_copy(aq, ap); len=vsnprintf(NULL, 0, format, ap); if(len>1024) len=1024; text=alloca((size_t)len+1); len=vsnprintf(text, (size_t)len+1, format, aq); va_end(aq); while(len>0 && text[len-1]=='\n') text[--len]='\0'; ``` If the formatted output is longer than 1024 bytes, `text[len-1]` reads past the end of the stack buffer. If the out-of-bounds byte happens to be `'\n'`, the loop also writes `'\0'` out of bounds. The demonstrated remote path is in server-side IMAP negotiation: `fd_getline` accepts client lines until its `ptr>65536` guard triggers, and `imap_server_middle` logs attacker-controlled command text on error: ```c s_log(LOG_ERR, "Unexpected client command %s", tail); ``` A remote client can therefore send an unexpected IMAP command longer than 1024 bytes and cause the resulting `%s` expansion to reach the vulnerable code. The available reproduction evidence shows an ASan-detected invalid read at `text[len-1]`; without sanitizers, the exact manifestation depends on adjacent stack state, but denial of service is a reasonable outcome. A reliable confidentiality or integrity impact was not established from the available technical evidence. Steps to reproduce: 1. Build `stunnel-5.72-8.el10` with sanitizers enabled: ```bash CFLAGS="-O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer" ./configure make -j ``` 2. Configure a service using server-side IMAP protocol negotiation (`protocol = imap`) and start stunnel. 3. Connect as a client and send an oversized unexpected IMAP command line longer than 1024 bytes, ending with `\r\n`. 4. Ensure the request reaches `fd_getline` in `src/network.c`, then `s_log(LOG_ERR, "Unexpected client command %s", tail);` in `src/protocol.c`, and finally the newline-stripping loop in `s_vlog` in `src/log.c`. 5. Observe an ASan invalid read, and potentially an invalid write, in `s_vlog` around `text[len-1]`. Mitigation: Until a fixed build is available, avoid exposing services configured with server-side IMAP protocol negotiation to untrusted clients, or restrict those services to trusted networks. Lowering log verbosity is not a reliable mitigation for the demonstrated path because it logs at `LOG_ERR`. Proposed Fix: Clamp negative and oversized results from the second `vsnprintf` call before reusing `len` in the newline-stripping loop. ```diff diff --git a/src/log.c b/src/log.c — a/src/log.c +++ b/src/log.c @@ -195,12 +195,19 @@ void s_vlog(int level, const char *format, va_list ap) { /* format the text to be logged */ va_copy(aq, ap); len=vsnprintf(NULL, 0, format, ap); + if(len<0) + len=0; if(len>1024) len=1024; text=alloca((size_t)len+1); len=vsnprintf(text, (size_t)len+1, format, aq); + { + int actual_len=vsnprintf(text, (size_t)len+1, format, aq); + if(actual_len<0) + actual_len=0; + if(actual_len>len) + actual_len=len; + len=actual_len; + } va_end(aq); while(len>0 && text[len-1]=='\n') text[--len]='\0'; /* strip trailing newlines */ ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use