git: 64ce9daab9ee - main - libfetch: Limit response line length
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 30 Sep 2026 16:55:46 UTC
The branch main has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=64ce9daab9ee49b4647f43141a830d7518723142
commit 64ce9daab9ee49b4647f43141a830d7518723142
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-09-30 16:54:25 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-09-30 16:54:25 +0000
libfetch: Limit response line length
When reading an FTP or HTTP response, error out if we read 64 kB before
hitting a newline. Otherwise a runaway or malicious server could have
us spinning for quite a while allocating more and more memory before we
gave up or crashed.
MFC after: 1 week
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D60007
---
lib/libfetch/common.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
index 431fd781ac6a..da0ea6f8aaeb 100644
--- a/lib/libfetch/common.c
+++ b/lib/libfetch/common.c
@@ -57,6 +57,8 @@
#include "fetch.h"
#include "common.h"
+/* Maximum length of a line, newline included, for fetch_getln() */
+#define FETCH_LINE_MAX 65536
/*** Local data **************************************************************/
@@ -1466,9 +1468,15 @@ fetch_getln(conn_t *conn)
/* look at the data we already have */
if (conn->pos < conn->buflen) {
conn->line = conn->buf + conn->pos;
- while (conn->pos < conn->buflen)
+ while (conn->pos < conn->buflen) {
if (conn->buf[conn->pos++] == '\n')
goto found;
+ if (conn->buf + conn->pos - conn->line >=
+ FETCH_LINE_MAX) {
+ errno = EPROTO;
+ goto fail;
+ }
+ }
/* reset for the upcoming memmove() */
conn->pos = conn->line - conn->buf;
}
@@ -1498,9 +1506,14 @@ fetch_getln(conn_t *conn)
if (rlen == 0)
break;
/* look for a newline */
- while (conn->pos < conn->buflen)
+ while (conn->pos < conn->buflen) {
if (conn->buf[conn->pos++] == '\n')
goto found;
+ if (conn->pos >= FETCH_LINE_MAX) {
+ errno = EPROTO;
+ goto fail;
+ }
+ }
/* do we need a bigger buffer? */
if (conn->buflen > conn->bufsize / 2) {
tmp = conn->buf;