Commit 39cfc744bf for ffmpeg
commit 39cfc744bfb1e8a94f77419cf316ef731b214daf
Author: Thomas Devoogdt <thomas@devoogdt.com>
Date: Sun Jul 19 19:23:52 2026 +0200
avformat/tls_gnutls, tls_openssl: fix AVERROR_EXIT in write callbacks
Returning 0 from a TLS write callback means "0 bytes sent", not "abort".
GnuTLS therefore retries the write forever, and OpenSSL reports success
while silently dropping the record. Report an error instead: errno =
EINTR, as required by the GnuTLS transport callback contract, and
c->io_err for OpenSSL, so that an interrupted ffurl_write() propagates
to the caller rather than hanging or losing data.
Signed-off-by: Thomas Devoogdt <thomas@devoogdt.com>
diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c
index aedbc66e56..c40c2cd7f3 100644
--- a/libavformat/tls_gnutls.c
+++ b/libavformat/tls_gnutls.c
@@ -475,9 +475,10 @@ static ssize_t gnutls_url_push(gnutls_transport_ptr_t transport,
int ret = ffurl_write(uc, buf, len);
if (ret >= 0)
return ret;
- if (ret == AVERROR_EXIT)
- return 0;
- if (ret == AVERROR(EAGAIN)) {
+ if (ret == AVERROR_EXIT) {
+ /* Use EINTR, not 0: returning 0 would cause GnuTLS to busy-spin. */
+ errno = EINTR;
+ } else if (ret == AVERROR(EAGAIN)) {
errno = EAGAIN;
} else {
errno = EIO;
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 789dae48a0..0075288d61 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -580,8 +580,9 @@ static int url_bio_bwrite(BIO *b, const char *buf, int len)
return ret;
BIO_clear_retry_flags(b);
if (ret == AVERROR_EXIT)
- return 0;
- if (ret == AVERROR(EAGAIN))
+ /* Don't return 0: that signals success and silently drops the data. */
+ c->io_err = ret;
+ else if (ret == AVERROR(EAGAIN))
BIO_set_retry_write(b);
else
c->io_err = ret;