PR #25505 opened by Marti2203
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25505
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25505.patch

`http_write_reply()` formats the reply into `char message[BUFFER_SIZE]` (8192 
bytes) with `snprintf()` and passes the return value to `ffurl_write()`. When 
the reply does not fit, that is the length it would have had, so 
`ffurl_write()` sends bytes from past the end of the stack buffer to the 
client. The reply includes the user's `-headers` (and `-content_type`), so in 
listen mode a long `-headers` value is enough:

```
ffmpeg -listen 1 -headers "X-Pad: $(head -c 39000 /dev/zero | tr '\0' 
b)"$'\r\n' -i http://127.0.0.1:18080/x -f null -
```

A client connecting to it receives a 39100-byte reply, of which only the first 
8191 bytes come from `message`; ASan reports:

```
ERROR: AddressSanitizer: stack-buffer-overflow
READ of size 39100 thread T0
    #0 __interceptor_send
    #1 tcp_write libavformat/tcp.c:295:11
    #2 retry_transfer_wrapper libavformat/avio.c:592:22
    #3 ffurl_write2 libavformat/avio.c:649:12
    #4 ffurl_write libavformat/url.h:207:12
    #5 http_write_reply libavformat/http.c:738:16
    #6 handle_http_errors libavformat/http.c:746:5
```

The patch fails with `AVERROR(EINVAL)` and an error message when the reply does 
not fit, rather than sending it. With it, the example above sends no reply and 
the open fails with an error; with short headers the reply is the same 108 
bytes as before.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified 
manually.

🤖 Generated with [Claude Code](https://claude.com/claude-code)



From 6aa41d0a850b0c79dfd37af9a8c78fdda530708d Mon Sep 17 00:00:00 2001
From: Martin Mirchev <[email protected]>
Date: Tue, 27 Oct 2026 10:00:15 +0800
Subject: [PATCH] avformat/http: do not send more than the reply buffer holds

http_write_reply() passed the return value of snprintf() to
ffurl_write(). When the reply did not fit into message[BUFFER_SIZE],
for example with a long -headers value in listen mode, that is the
length the reply would have had, so bytes from past the end of the
stack buffer were sent to the client. Fail instead.

Signed-off-by: Martin Mirchev <[email protected]>
---
 libavformat/http.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavformat/http.c b/libavformat/http.c
index 2f4f522363a..86fcc7b8879 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -734,6 +734,10 @@ static int http_write_reply(URLContext* h, int status_code)
                  content_type,
                  s->headers ? s->headers : "");
     }
+    if (message_len < 0 || message_len >= sizeof(message)) {
+        av_log(h, AV_LOG_ERROR, "HTTP reply header too long\n");
+        return AVERROR(EINVAL);
+    }
     av_log(h, AV_LOG_TRACE, "HTTP reply header: \n%s----\n", message);
     if ((ret = ffurl_write(s->hd, message, message_len)) < 0)
         return ret;
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to