Blame SOURCES/wget-1.14-CVE-2014-4877.patch

96e81d
From 043366ac3248a58662a6fbf47a1dd688a75d0e78 Mon Sep 17 00:00:00 2001
96e81d
From: Darshit Shah <darnir@gmail.com>
96e81d
Date: Mon, 8 Sep 2014 00:41:17 +0530
96e81d
Subject: [PATCH 1/2] Fix R7-2014-15: Arbitrary Symlink Access
96e81d
96e81d
Wget was susceptible to a symlink attack which could create arbitrary
96e81d
files, directories or symbolic links and set their permissions when
96e81d
retrieving a directory recursively through FTP. This commit changes the
96e81d
default settings in Wget such that Wget no longer creates local symbolic
96e81d
links, but rather traverses them and retrieves the pointed-to file in
96e81d
such a retrieval.
96e81d
96e81d
The old behaviour can be attained by passing the --retr-symlinks=no
96e81d
option to the Wget invokation command.
96e81d
---
96e81d
 doc/wget.texi | 23 ++++++++++++-----------
96e81d
 src/init.c    | 16 ++++++++++++++++
96e81d
 2 files changed, 28 insertions(+), 11 deletions(-)
96e81d
96e81d
diff --git a/doc/wget.texi b/doc/wget.texi
96e81d
index a31eb5e..f54e98d 100644
96e81d
--- a/doc/wget.texi
96e81d
+++ b/doc/wget.texi
96e81d
@@ -1883,17 +1883,18 @@ Preserve remote file permissions instead of permissions set by umask.
96e81d
 
96e81d
 @cindex symbolic links, retrieving
96e81d
 @item --retr-symlinks
96e81d
-Usually, when retrieving @sc{ftp} directories recursively and a symbolic
96e81d
-link is encountered, the linked-to file is not downloaded.  Instead, a
96e81d
-matching symbolic link is created on the local filesystem.  The
96e81d
-pointed-to file will not be downloaded unless this recursive retrieval
96e81d
-would have encountered it separately and downloaded it anyway.
96e81d
-
96e81d
-When @samp{--retr-symlinks} is specified, however, symbolic links are
96e81d
-traversed and the pointed-to files are retrieved.  At this time, this
96e81d
-option does not cause Wget to traverse symlinks to directories and
96e81d
-recurse through them, but in the future it should be enhanced to do
96e81d
-this.
96e81d
+By default, when retrieving @sc{ftp} directories recursively and a symbolic link
96e81d
+is encountered, the symbolic link is traversed and the pointed-to files are
96e81d
+retrieved.  Currently, Wget does not traverse symbolic links to directories to
96e81d
+download them recursively, though this feature may be added in the future.
96e81d
+
96e81d
+When @samp{--retr-symlinks=no} is specified, the linked-to file is not
96e81d
+downloaded.  Instead, a matching symbolic link is created on the local
96e81d
+filesystem.  The pointed-to file will not be retrieved unless this recursive
96e81d
+retrieval would have encountered it separately and downloaded it anyway.  This
96e81d
+option poses a security risk where a malicious FTP Server may cause Wget to
96e81d
+write to files outside of the intended directories through a specially crafted
96e81d
+@sc{.listing} file.
96e81d
 
96e81d
 Note that when retrieving a file (not a directory) because it was
96e81d
 specified on the command-line, rather than because it was recursed to,
96e81d
diff --git a/src/init.c b/src/init.c
96e81d
index 93e95f8..94b6f8b 100644
96e81d
--- a/src/init.c
96e81d
+++ b/src/init.c
96e81d
@@ -366,6 +366,22 @@ defaults (void)
96e81d
 
96e81d
   opt.dns_cache = true;
96e81d
   opt.ftp_pasv = true;
96e81d
+  /* 2014-09-07  Darshit Shah  <darnir@gmail.com>
96e81d
+   * opt.retr_symlinks is set to true by default. Creating symbolic links on the
96e81d
+   * local filesystem pose a security threat by malicious FTP Servers that
96e81d
+   * server a specially crafted .listing file akin to this:
96e81d
+   *
96e81d
+   * lrwxrwxrwx   1 root     root           33 Dec 25  2012 JoCxl6d8rFU -> /
96e81d
+   * drwxrwxr-x  15 1024     106          4096 Aug 28 02:02 JoCxl6d8rFU
96e81d
+   *
96e81d
+   * A .listing file in this fashion makes Wget susceptiple to a symlink attack
96e81d
+   * wherein the attacker is able to create arbitrary files, directories and
96e81d
+   * symbolic links on the target system and even set permissions.
96e81d
+   *
96e81d
+   * Hence, by default Wget attempts to retrieve the pointed-to files and does
96e81d
+   * not create the symbolic links locally.
96e81d
+   */
96e81d
+  opt.retr_symlinks = true;
96e81d
 
96e81d
 #ifdef HAVE_SSL
96e81d
   opt.check_cert = true;
96e81d
-- 
96e81d
2.1.0
96e81d
96e81d
From bfa8c9cc9937f686a4de110e49710061267f8d9e Mon Sep 17 00:00:00 2001
96e81d
From: Darshit Shah <darnir@gmail.com>
96e81d
Date: Mon, 8 Sep 2014 15:07:45 +0530
96e81d
Subject: [PATCH 2/2] Add checks for valid listing file in FTP
96e81d
96e81d
When Wget retrieves a file through FTP, it first downloads a .listing
96e81d
file and parses it for information about the files and other metadata.
96e81d
Some servers may serve invalid .listing files. This patch checks for one
96e81d
such known inconsistency wherein multiple lines in a listing file have
96e81d
the same name. Such a filesystem is clearly not possible and hence we
96e81d
eliminate duplicate entries here.
96e81d
96e81d
Signed-off-by: Darshit Shah <darnir@gmail.com>
96e81d
---
96e81d
 src/ftp.c     | 27 +++++++++++++++++++++++++--
96e81d
 1 file changed, 25 insertions(+), 2 deletions(-)
96e81d
96e81d
diff --git a/src/ftp.c b/src/ftp.c
96e81d
index 2d54333..054cb61 100644
96e81d
--- a/src/ftp.c
96e81d
+++ b/src/ftp.c
96e81d
@@ -2211,6 +2211,29 @@ has_insecure_name_p (const char *s)
96e81d
   return false;
96e81d
 }
96e81d
 
96e81d
+/* Test if the file node is invalid. This can occur due to malformed or
96e81d
+ * maliciously crafted listing files being returned by the server.
96e81d
+ *
96e81d
+ * Currently, this function only tests if there are multiple entries in the
96e81d
+ * listing file by the same name. However this function can be expanded as more
96e81d
+ * such illegal listing formats are discovered. */
96e81d
+static bool
96e81d
+is_invalid_entry (struct fileinfo *f)
96e81d
+{
96e81d
+  struct fileinfo *cur;
96e81d
+  cur = f;
96e81d
+  char *f_name = f->name;
96e81d
+  /* If the node we're currently checking has a duplicate later, we eliminate
96e81d
+   * the current node and leave the next one intact. */
96e81d
+  while (cur->next)
96e81d
+    {
96e81d
+      cur = cur->next;
96e81d
+      if (strcmp(f_name, cur->name) == 0)
96e81d
+          return true;
96e81d
+    }
96e81d
+  return false;
96e81d
+}
96e81d
+
96e81d
 /* A near-top-level function to retrieve the files in a directory.
96e81d
    The function calls ftp_get_listing, to get a linked list of files.
96e81d
    Then it weeds out the file names that do not match the pattern.
96e81d
@@ -2248,11 +2271,11 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
96e81d
             f = f->next;
96e81d
         }
96e81d
     }
96e81d
-  /* Remove all files with possible harmful names */
96e81d
+  /* Remove all files with possible harmful names or invalid entries. */
96e81d
   f = start;
96e81d
   while (f)
96e81d
     {
96e81d
-      if (has_insecure_name_p (f->name))
96e81d
+      if (has_insecure_name_p (f->name) || is_invalid_entry (f))
96e81d
         {
96e81d
           logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
96e81d
                      quote (f->name));
96e81d
-- 
96e81d
2.1.0
96e81d