blob: 202488f75c23d38aae46f26444731e9a6256e2ee [file] [log] [blame]
Patrick Williams93c203f2021-10-06 16:15:23 -05001From 98ccabf68e5b3f0a177bd1925581753d10041448 Mon Sep 17 00:00:00 2001
2From: Simon Josefsson <simon@josefsson.org>
3Date: Wed, 1 Sep 2021 09:09:50 +0200
4Subject: [PATCH] ftp: check that PASV/LSPV addresses match.
5
6* NEWS: Mention change.
7* ftp/ftp.c (initconn): Validate returned addresses.
8
9CVE: CVE-2021-40491
10
11Upstream-Status: Backport
12[https://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=58cb043b190fd04effdaea7c9403416b436e50dd]
13
14Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
15---
16 NEWS | 9 +++++++++
17 ftp/ftp.c | 21 +++++++++++++++++++++
18 2 files changed, 30 insertions(+)
19
20diff --git a/NEWS b/NEWS
21index 7c5e62c..bd9a4da 100644
22--- a/NEWS
23+++ b/NEWS
24@@ -4,6 +4,15 @@ GNU inetutils NEWS -- history of user-visible changes.
25
26 ** ftp
27
28+The ftp client now validate addresses returned by PASV/LSPV responses,
29+to make sure they match the server address. Reported by ZeddYu Lu in
30+<https://lists.gnu.org/archive/html/bug-inetutils/2021-06/msg00002.html>.
31+
32+Thanks to Luke Mewburn <lukem@netbsd.org> for discussion and fix to
33+NetBSD code, we used a similar solution.
34+
35+** ftp
36+
37 Disable use of readline when environment variable TERM is unset or set
38 to "dumb" (caused problems with Emacs AngeFTP on MacOS). Thanks to
39 Alex Bochannek for report, debugging and patch.
40diff --git a/ftp/ftp.c b/ftp/ftp.c
41index d21dbdd..7513539 100644
42--- a/ftp/ftp.c
43+++ b/ftp/ftp.c
44@@ -1365,6 +1365,13 @@ initconn (void)
45 uint32_t *pu32 = (uint32_t *) &data_addr_sa4->sin_addr.s_addr;
46 pu32[0] = htonl ( (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | h[3]);
47 }
48+ if (data_addr_sa4->sin_addr.s_addr
49+ != ((struct sockaddr_in *) &hisctladdr)->sin_addr.s_addr)
50+ {
51+ printf ("Passive mode address mismatch.\n");
52+ (void) command ("ABOR"); /* Cancel any open connection. */
53+ goto bad;
54+ }
55 } /* LPSV IPv4 */
56 else /* IPv6 */
57 {
58@@ -1395,6 +1402,13 @@ initconn (void)
59 pu32[2] = htonl ( (h[8] << 24) | (h[9] << 16) | (h[10] << 8) | h[11]);
60 pu32[3] = htonl ( (h[12] << 24) | (h[13] << 16) | (h[14] << 8) | h[15]);
61 }
62+ if (data_addr_sa6->sin6_addr.s6_addr
63+ != ((struct sockaddr_in6 *) &hisctladdr)->sin6_addr.s6_addr)
64+ {
65+ printf ("Passive mode address mismatch.\n");
66+ (void) command ("ABOR"); /* Cancel any open connection. */
67+ goto bad;
68+ }
69 } /* LPSV IPv6 */
70 }
71 else /* !EPSV && !LPSV */
72@@ -1415,6 +1429,13 @@ initconn (void)
73 | ((a2 & 0xff) << 8) | (a3 & 0xff) );
74 data_addr_sa4->sin_port =
75 htons (((p0 & 0xff) << 8) | (p1 & 0xff));
76+ if (data_addr_sa4->sin_addr.s_addr
77+ != ((struct sockaddr_in *) &hisctladdr)->sin_addr.s_addr)
78+ {
79+ printf ("Passive mode address mismatch.\n");
80+ (void) command ("ABOR"); /* Cancel any open connection. */
81+ goto bad;
82+ }
83 } /* PASV */
84 else
85 {
86--
872.17.1
88