From 98ccabf68e5b3f0a177bd1925581753d10041448 Mon Sep 17 00:00:00 2001
|
From: Simon Josefsson <simon@josefsson.org>
|
Date: Wed, 1 Sep 2021 09:09:50 +0200
|
Subject: [PATCH] ftp: check that PASV/LSPV addresses match.
|
|
* NEWS: Mention change.
|
* ftp/ftp.c (initconn): Validate returned addresses.
|
|
CVE: CVE-2021-40491
|
|
Upstream-Status: Backport
|
[https://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=58cb043b190fd04effdaea7c9403416b436e50dd]
|
|
Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
|
---
|
NEWS | 9 +++++++++
|
ftp/ftp.c | 21 +++++++++++++++++++++
|
2 files changed, 30 insertions(+)
|
|
diff --git a/NEWS b/NEWS
|
index 7c5e62c..bd9a4da 100644
|
--- a/NEWS
|
+++ b/NEWS
|
@@ -4,6 +4,15 @@ GNU inetutils NEWS -- history of user-visible changes.
|
|
** ftp
|
|
+The ftp client now validate addresses returned by PASV/LSPV responses,
|
+to make sure they match the server address. Reported by ZeddYu Lu in
|
+<https://lists.gnu.org/archive/html/bug-inetutils/2021-06/msg00002.html>.
|
+
|
+Thanks to Luke Mewburn <lukem@netbsd.org> for discussion and fix to
|
+NetBSD code, we used a similar solution.
|
+
|
+** ftp
|
+
|
Disable use of readline when environment variable TERM is unset or set
|
to "dumb" (caused problems with Emacs AngeFTP on MacOS). Thanks to
|
Alex Bochannek for report, debugging and patch.
|
diff --git a/ftp/ftp.c b/ftp/ftp.c
|
index d21dbdd..7513539 100644
|
--- a/ftp/ftp.c
|
+++ b/ftp/ftp.c
|
@@ -1365,6 +1365,13 @@ initconn (void)
|
uint32_t *pu32 = (uint32_t *) &data_addr_sa4->sin_addr.s_addr;
|
pu32[0] = htonl ( (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | h[3]);
|
}
|
+ if (data_addr_sa4->sin_addr.s_addr
|
+ != ((struct sockaddr_in *) &hisctladdr)->sin_addr.s_addr)
|
+ {
|
+ printf ("Passive mode address mismatch.\n");
|
+ (void) command ("ABOR"); /* Cancel any open connection. */
|
+ goto bad;
|
+ }
|
} /* LPSV IPv4 */
|
else /* IPv6 */
|
{
|
@@ -1395,6 +1402,13 @@ initconn (void)
|
pu32[2] = htonl ( (h[8] << 24) | (h[9] << 16) | (h[10] << 8) | h[11]);
|
pu32[3] = htonl ( (h[12] << 24) | (h[13] << 16) | (h[14] << 8) | h[15]);
|
}
|
+ if (data_addr_sa6->sin6_addr.s6_addr
|
+ != ((struct sockaddr_in6 *) &hisctladdr)->sin6_addr.s6_addr)
|
+ {
|
+ printf ("Passive mode address mismatch.\n");
|
+ (void) command ("ABOR"); /* Cancel any open connection. */
|
+ goto bad;
|
+ }
|
} /* LPSV IPv6 */
|
}
|
else /* !EPSV && !LPSV */
|
@@ -1415,6 +1429,13 @@ initconn (void)
|
| ((a2 & 0xff) << 8) | (a3 & 0xff) );
|
data_addr_sa4->sin_port =
|
htons (((p0 & 0xff) << 8) | (p1 & 0xff));
|
+ if (data_addr_sa4->sin_addr.s_addr
|
+ != ((struct sockaddr_in *) &hisctladdr)->sin_addr.s_addr)
|
+ {
|
+ printf ("Passive mode address mismatch.\n");
|
+ (void) command ("ABOR"); /* Cancel any open connection. */
|
+ goto bad;
|
+ }
|
} /* PASV */
|
else
|
{
|
--
|
2.17.1
|