Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Michal Ruprich
87395f725f Fix for CVE-2026-15146, CVE-2026-58470, CVE-2026-58471, CVE-2026-58472 2026-07-15 17:13:00 +02:00
5 changed files with 343 additions and 1 deletions

View file

@ -0,0 +1,120 @@
From 4f85853f641863d5915786a8413e1a213726a62b Mon Sep 17 00:00:00 2001
From: Acts1631 <acts1631kjv@proton.me>
Date: Sun, 5 Jul 2026 17:22:55 -0400
Subject: ftp: validate PASV/LPSV response address against control connection
peer
* src/ftp-basic.c (ftp_pasv): Reject if peer address doesn't match advertised
address,
(ftp_lpsv): Likewise.
ftp_pasv() and ftp_lpsv() copied the IP address and port advertised in
the server's 227 response without checking that it matched the peer
of the control connection. A malicious or compromised FTP server
could therefore direct wget's data connection to an arbitrary host and
port of its choosing (e.g. an internal service unreachable from the
attacker directly), which is a server-side request forgery.
ftp_epsv() was already safe since it only extracts a port and reuses
the pre-filled control-connection address.
Fix ftp_pasv() and ftp_lpsv() the same way: capture the control
connection's peer address via socket_ip_address() before parsing the
response, and reject the response (FTPINVPASV) if the parsed address
does not match.
Verified with a fake FTP server that returns a PASV response pointing
at a different loopback address (127.0.0.2 instead of the real peer
127.0.0.1): before the fix wget connects to the spoofed address, after
the fix it rejects the response with "Cannot parse PASV response."
Legitimate transfers using a correctly-addressed PASV response
continue to work.
Copyright-paperwork-exempt: Yes
---
src/ftp-basic.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/src/ftp-basic.c b/src/ftp-basic.c
index 4870256a..0f4bb821 100644
--- a/src/ftp-basic.c
+++ b/src/ftp-basic.c
@@ -623,10 +623,19 @@ ftp_pasv (int csock, ip_address *addr, int *port)
int nwritten, i;
uerr_t err;
unsigned char tmp[6];
+ ip_address peer_addr;
assert (addr != NULL);
assert (port != NULL);
+ /* Remember who we are talking to on the control connection, so that
+ the address returned in the PASV response can be checked below.
+ Accepting an arbitrary server-supplied address would let a
+ malicious FTP server redirect our data connection to any host of
+ its choosing (SSRF). */
+ if (!socket_ip_address (csock, &peer_addr, ENDPOINT_PEER))
+ return FTPINVPASV;
+
xzero (*addr);
/* Form the request. */
@@ -677,6 +686,16 @@ ftp_pasv (int csock, ip_address *addr, int *port)
memcpy (IP_INADDR_DATA (addr), tmp, 4);
*port = ((tmp[4] << 8) & 0xff00) + tmp[5];
+ /* Reject the response if the advertised address does not match the
+ control connection's peer. */
+ if (peer_addr.family != AF_INET
+ || memcmp (IP_INADDR_DATA (addr), IP_INADDR_DATA (&peer_addr), 4) != 0)
+ {
+ xzero (*addr);
+ *port = 0;
+ return FTPINVPASV;
+ }
+
return FTPOK;
}
@@ -692,10 +711,19 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
uerr_t err;
unsigned char tmp[16];
unsigned char tmpprt[2];
+ ip_address peer_addr;
assert (addr != NULL);
assert (port != NULL);
+ /* Remember who we are talking to on the control connection, so that
+ the address returned in the LPSV response can be checked below.
+ Accepting an arbitrary server-supplied address would let a
+ malicious FTP server redirect our data connection to any host of
+ its choosing (SSRF). */
+ if (!socket_ip_address (csock, &peer_addr, ENDPOINT_PEER))
+ return FTPINVPASV;
+
xzero (*addr);
/* Form the request. */
@@ -842,6 +870,18 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
DEBUGP (("*port is: %d\n", *port));
}
+ /* Reject the response if the advertised address does not match the
+ control connection's peer. */
+ if (peer_addr.family != addr->family
+ || memcmp (IP_INADDR_DATA (addr), IP_INADDR_DATA (&peer_addr),
+ af == 4 ? 4 : 16) != 0)
+ {
+ xzero (*addr);
+ *port = 0;
+ xfree (respline);
+ return FTPINVPASV;
+ }
+
xfree (respline);
return FTPOK;
}
--
cgit v1.3

View file

@ -0,0 +1,76 @@
From 43d3ba9336bc94937e6fae2365c6ffd30c34ffcf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20R=C3=BChsen?= <tim.ruehsen@gmx.de>
Date: Mon, 29 Jun 2026 18:57:54 +0200
Subject: [PATCH] * src/http.c (parse_content_range): Fix integer overflow
Reported-by: TristanInSec@gmail.com
---
src/http.c | 35 ++++++++++++++++++++++++-----------
1 file changed, 24 insertions(+), 11 deletions(-)
diff --git a/src/http.c b/src/http.c
index 61d83df1..f447c7f7 100644
--- a/src/http.c
+++ b/src/http.c
@@ -914,6 +914,7 @@ parse_content_range (const char *hdr, wgint *first_byte_ptr,
wgint *last_byte_ptr, wgint *entity_length_ptr)
{
wgint num;
+ char *end;
/* Ancient versions of Netscape proxy server, presumably predating
rfc2068, sent out `Content-Range' without the "bytes"
@@ -932,27 +933,39 @@ parse_content_range (const char *hdr, wgint *first_byte_ptr,
}
if (!c_isdigit (*hdr))
return false;
- for (num = 0; c_isdigit (*hdr); hdr++)
- num = 10 * num + (*hdr - '0');
- if (*hdr != '-' || !c_isdigit (*(hdr + 1)))
+
+ errno = 0;
+ num = strtol(hdr, &end, 10);
+ if (errno == ERANGE)
+ return false;
+ hdr = end;
+
+ if (*hdr++ != '-' || !c_isdigit (*hdr))
return false;
*first_byte_ptr = num;
- ++hdr;
- for (num = 0; c_isdigit (*hdr); hdr++)
- num = 10 * num + (*hdr - '0');
- if (*hdr != '/')
+
+ errno = 0;
+ num = strtol(hdr, &end, 10);
+ if (errno == ERANGE)
+ return false;
+ hdr = end;
+
+ if (*hdr++ != '/')
return false;
*last_byte_ptr = num;
- if (!(c_isdigit (*(hdr + 1)) || *(hdr + 1) == '*'))
+ if (!(c_isdigit (*hdr) || *hdr == '*'))
return false;
if (*last_byte_ptr < *first_byte_ptr)
return false;
- ++hdr;
if (*hdr == '*')
num = -1;
else
- for (num = 0; c_isdigit (*hdr); hdr++)
- num = 10 * num + (*hdr - '0');
+ {
+ errno = 0;
+ num = strtol(hdr, NULL, 10);
+ if (errno == ERANGE)
+ return false;
+ }
*entity_length_ptr = num;
if ((*entity_length_ptr <= *last_byte_ptr) && *entity_length_ptr != -1)
return false;
--
GitLab

View file

@ -0,0 +1,68 @@
From c2640fe5171c59f87c58dc9fcb195b2d18b010ee Mon Sep 17 00:00:00 2001
From: Arkadi Vainbrand <arkadva8@gmail.com>
Date: Tue, 13 Jan 2026 12:22:04 +0200
Subject: [PATCH] Fix buffer size handling in filename conversion
* src/url.c (convert_fname): Fix buffer overflow.
Copyright-paperwork-exempt: Yes
Signed-off-by: Arkadi Vainbrand <arkadva8@gmail.com>
---
src/url.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/url.c b/src/url.c
index 7540e90f..f334456c 100644
--- a/src/url.c
+++ b/src/url.c
@@ -1614,7 +1614,7 @@ convert_fname (char *fname)
const char *from_encoding = opt.encoding_remote;
const char *to_encoding = opt.locale;
iconv_t cd;
- size_t len, done, inlen, outlen;
+ size_t len, inlen, outlen;
char *s;
const char *orig_fname;
@@ -1636,7 +1636,6 @@ convert_fname (char *fname)
inlen = strlen (fname);
len = outlen = inlen * 2;
converted_fname = s = xmalloc (outlen + 1);
- done = 0;
for (;;)
{
@@ -1644,7 +1643,7 @@ convert_fname (char *fname)
if (iconv (cd, (ICONV_CONST char **) &fname, &inlen, &s, &outlen) == 0
&& iconv (cd, NULL, NULL, &s, &outlen) == 0)
{
- *(converted_fname + len - outlen - done) = '\0';
+ *s = '\0';
iconv_close (cd);
DEBUGP (("Converted file name '%s' (%s) -> '%s' (%s)\n",
orig_fname, from_encoding, converted_fname, to_encoding));
@@ -1667,10 +1666,17 @@ convert_fname (char *fname)
}
else if (errno == E2BIG) /* Output buffer full */
{
- done = len;
- len = outlen = done + inlen * 2;
- converted_fname = xrealloc (converted_fname, outlen + 1);
- s = converted_fname + done;
+ size_t used = s - converted_fname;
+ size_t newlen = used + inlen * 2 + 1;
+
+ /* Ensure we actually grow the buffer */
+ if (newlen <= len)
+ newlen = len * 2;
+
+ converted_fname = xrealloc (converted_fname, newlen + 1);
+ len = newlen;
+ s = converted_fname + used;
+ outlen = len - used;
}
else /* Weird, we got an unspecified error */
{
--
GitLab

View file

@ -0,0 +1,71 @@
From dd692d9cea5335b181d877ae917fe6e75587a812 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20R=C3=BChsen?= <tim.ruehsen@gmx.de>
Date: Mon, 29 Jun 2026 19:13:15 +0200
Subject: [PATCH] * src/convert.c (html_quote_string): Fix integer+buffer
overflow
Reported-by: TristanInSec@gmail.com
---
src/convert.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/src/convert.c b/src/convert.c
index feb90a35..3baec850 100644
--- a/src/convert.c
+++ b/src/convert.c
@@ -36,6 +36,7 @@ as that of the covered work. */
#include <unistd.h>
#include <errno.h>
#include <assert.h>
+#include <intprops.h>
#include "convert.h"
#include "url.h"
#include "recur.h"
@@ -1178,21 +1179,37 @@ html_quote_string (const char *s)
{
const char *b = s;
char *p, *res;
- int i;
+ size_t i;
+ int ok;
/* Pass through the string, and count the new size. */
- for (i = 0; *s; s++, i++)
+ for (i = 0; *s; s++)
{
if (*s == '&')
- i += 4; /* `amp;' */
+ ok = INT_ADD_OK (i, 4, &i); /* `amp;' */
else if (*s == '<' || *s == '>')
- i += 3; /* `lt;' and `gt;' */
+ ok = INT_ADD_OK (i, 3, &i); /* `lt;' and `gt;' */
else if (*s == '\"')
- i += 5; /* `quot;' */
+ ok = INT_ADD_OK (i, 5, &i); /* `quot;' */
else if (*s == ' ')
- i += 4; /* #32; */
+ ok = INT_ADD_OK (i, 4, &i); /* #32; */
+ else
+ ok = INT_ADD_OK (i, 1, &i);
+
+ if (!ok)
+ {
+ DEBUGP (("Overflow detected in html_quote_string().\n"));
+ abort();
+ }
}
- res = xmalloc (i + 1);
+
+ if (!INT_ADD_OK (i, 1, &i))
+ {
+ DEBUGP (("Overflow detected in html_quote_string().\n"));
+ abort();
+ }
+
+ res = xmalloc (i);
s = b;
for (p = res; *s; s++)
{
--
GitLab

View file

@ -1,7 +1,7 @@
Summary: A utility for retrieving files using the HTTP or FTP protocols
Name: wget1
Version: 1.25.0
Release: 3%{?dist}
Release: 4%{?dist}
# Generally wget is distributed under GPLv3 or later but there are files in lib/ directory
# which are under LGPLv2.1 or later and are actually built into the resulting rpm.
# This version of wget is built with gnutls so I believe that the 'with openssl'
@ -11,6 +11,10 @@ Url: http://www.gnu.org/software/wget/
Source: https://ftp.gnu.org/gnu/wget/wget-%{version}.tar.gz
Patch1: wget-1.17-path.patch
Patch2: wget-1.25-fix-cve-2026-15146.patch
Patch3: wget-1.25-fix-cve-2026-58470.patch
Patch4: wget-1.25-fix-cve-2026-58471.patch
Patch5: wget-1.25-fix-cve-2026-58472.patch
Provides: bundled(gnulib)
# needed for test suite
@ -112,6 +116,9 @@ echo ".so man1/%{name}.1" > %{buildroot}%{_mandir}/man1/wget.1
%config(noreplace) %{_sysconfdir}/wgetrc
%changelog
* Wed Jul 15 2026 Michal Ruprich <mruprich@redhat.com> - 1.25.0-4
- Fix for CVE-2026-15146, CVE-2026-58470, CVE-2026-58471, CVE-2026-58472
* Sat Jan 17 2026 Fedora Release Engineering <releng@fedoraproject.org> - 1.25.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild