Commit fc0db829b8 for freeswitch.com
commit fc0db829b87d1a5a3043e355b4294c41851b13c6
Author: Dmitry Verenitsin <morbit85@gmail.com>
Date: Sat Aug 8 21:55:22 2026 +0500
Merge commit from fork
`rtmp_handle_control()` formats the control-message body into a fixed
200-byte stack buffer with an unbounded `sprintf` loop whose iteration
count is the wire message length. A body of ~70 bytes or more runs the
write off the end of `buf`, corrupting the stack frame; the length is
taken straight from the chunk header and reaches this path before any
login, so a remote peer can trigger it.
Bound the loop with `snprintf` against the remaining space and stop when
the buffer is full. This also caps the iteration count, so the loop can
no longer read `state->buf` past what was reassembled. The hex dump is
debug-only output, so capping it changes nothing operational.
diff --git a/src/mod/endpoints/mod_rtmp/rtmp.c b/src/mod/endpoints/mod_rtmp/rtmp.c
index 285bc81103..74097f13b3 100644
--- a/src/mod/endpoints/mod_rtmp/rtmp.c
+++ b/src/mod/endpoints/mod_rtmp/rtmp.c
@@ -81,11 +81,18 @@ void rtmp_handle_control(rtmp_session_t *rsession, int amfnumber)
rtmp_state_t *state = &rsession->amfstate[amfnumber];
char buf[200] = { 0 };
char *p = buf;
+ char *end = buf + sizeof(buf);
int type = state->buf[0] << 8 | state->buf[1];
int i;
- for (i = 2; i < state->origlen; i++) {
- p += sprintf(p, "%02x ", state->buf[i] & 0xFF);
+ for (i = 2; i < state->origlen && p < end; i++) {
+ int n = snprintf(p, end - p, "%02x ", state->buf[i] & 0xFF);
+
+ if (n <= 0 || n >= end - p) {
+ break;
+ }
+
+ p += n;
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_DEBUG, "Control (%d): %s\n", type, buf);