Patrick Williams | 93c203f | 2021-10-06 16:15:23 -0500 | [diff] [blame] | 1 | From 98ccabf68e5b3f0a177bd1925581753d10041448 Mon Sep 17 00:00:00 2001 |
| 2 | From: Simon Josefsson <simon@josefsson.org> |
| 3 | Date: Wed, 1 Sep 2021 09:09:50 +0200 |
| 4 | Subject: [PATCH] ftp: check that PASV/LSPV addresses match. |
| 5 | |
| 6 | * NEWS: Mention change. |
| 7 | * ftp/ftp.c (initconn): Validate returned addresses. |
| 8 | |
| 9 | CVE: CVE-2021-40491 |
| 10 | |
| 11 | Upstream-Status: Backport |
| 12 | [https://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=58cb043b190fd04effdaea7c9403416b436e50dd] |
| 13 | |
| 14 | Signed-off-by: Yi Zhao <yi.zhao@windriver.com> |
| 15 | --- |
| 16 | NEWS | 9 +++++++++ |
| 17 | ftp/ftp.c | 21 +++++++++++++++++++++ |
| 18 | 2 files changed, 30 insertions(+) |
| 19 | |
| 20 | diff --git a/NEWS b/NEWS |
| 21 | index 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. |
| 40 | diff --git a/ftp/ftp.c b/ftp/ftp.c |
| 41 | index 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 | -- |
| 87 | 2.17.1 |
| 88 | |