Index: vsftpd-2.0.7/access.c
===================================================================
--- vsftpd-2.0.7.orig/access.c	2008-02-02 02:30:41.000000000 +0100
+++ vsftpd-2.0.7/access.c	2011-03-07 15:47:30.879484659 +0100
@@ -16,6 +16,7 @@
 vsf_access_check_file(const struct mystr* p_filename_str)
 {
   static struct mystr s_access_str;
+  unsigned int iters = 0;
 
   if (!tunable_deny_file)
   {
@@ -25,7 +26,7 @@
   {
     str_alloc_text(&s_access_str, tunable_deny_file);
   }
-  if (vsf_filename_passes_filter(p_filename_str, &s_access_str))
+  if (vsf_filename_passes_filter(p_filename_str, &s_access_str, &iters))
   {
     return 0;
   }
@@ -45,6 +46,7 @@
 vsf_access_check_file_visible(const struct mystr* p_filename_str)
 {
   static struct mystr s_access_str;
+  unsigned int iters = 0;
 
   if (!tunable_hide_file)
   {
@@ -54,7 +56,7 @@
   {
     str_alloc_text(&s_access_str, tunable_hide_file);
   }
-  if (vsf_filename_passes_filter(p_filename_str, &s_access_str))
+  if (vsf_filename_passes_filter(p_filename_str, &s_access_str, &iters))
   {
     return 0;
   }
Index: vsftpd-2.0.7/defs.h
===================================================================
--- vsftpd-2.0.7.orig/defs.h	2008-02-02 02:30:41.000000000 +0100
+++ vsftpd-2.0.7/defs.h	2011-03-07 15:47:30.880484698 +0100
@@ -10,6 +10,7 @@
 #define VSFTP_MAX_COMMAND_LINE  4096
 #define VSFTP_DATA_BUFSIZE      65536
 #define VSFTP_DIR_BUFSIZE       16384
+#define VSFTP_MATCHITERS_MAX    1000
 #define VSFTP_PATH_MAX          4096
 #define VSFTP_CONF_FILE_MAX     100000
 #define VSFTP_LISTEN_BACKLOG    32
Index: vsftpd-2.0.7/ftpdataio.c
===================================================================
--- vsftpd-2.0.7.orig/ftpdataio.c	2008-07-29 06:54:55.000000000 +0200
+++ vsftpd-2.0.7/ftpdataio.c	2011-03-07 15:49:09.341347358 +0100
@@ -104,7 +104,6 @@
     if (!vsf_sysutil_sockaddr_addr_equal(p_sess->p_remote_addr, p_accept_addr))
     {
       vsf_cmdio_write(p_sess, FTP_BADSENDCONN, "Security: Bad IP connecting.");
-      vsf_sysutil_close(remote_fd);
       vsf_sysutil_sockaddr_clear(&p_accept_addr);
       return -1;
     }
@@ -346,6 +345,7 @@
       if (retval != 0)
       {
         failed = 1;
+        vsf_sysutil_closedir(p_subdir);
         break;
       }
       retval = transfer_dir_internal(p_sess, is_control, p_subdir, &sub_str,
Index: vsftpd-2.0.7/ls.c
===================================================================
--- vsftpd-2.0.7.orig/ls.c	2008-02-02 02:30:41.000000000 +0100
+++ vsftpd-2.0.7/ls.c	2011-03-07 15:47:30.924486425 +0100
@@ -9,6 +9,7 @@
 
 #include "ls.h"
 #include "access.h"
+#include "defs.h"
 #include "str.h"
 #include "strlist.h"
 #include "sysstr.h"
@@ -116,7 +117,9 @@
     /* If we have an ls option which is a filter, apply it */
     if (!str_isempty(p_filter_str))
     {
-      if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str))
+      unsigned int iters = 0;
+      if (!vsf_filename_passes_filter(&s_next_filename_str, p_filter_str,
+                                      &iters))
       {
         continue;
       }
@@ -215,7 +218,8 @@
 
 int
 vsf_filename_passes_filter(const struct mystr* p_filename_str,
-                           const struct mystr* p_filter_str)
+                           const struct mystr* p_filter_str,
+                           unsigned int* iters)
 {
   /* A simple routine to match a filename against a pattern.
    * This routine is used instead of e.g. fnmatch(3), because we should be
@@ -242,12 +246,13 @@
   str_copy(&filter_remain_str, p_filter_str);
   str_copy(&name_remain_str, p_filename_str);
 
-  while (!str_isempty(&filter_remain_str))
+  while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX)
   {
     static struct mystr s_match_needed_str;
     /* Locate next special token */
     struct str_locate_result locate_result =
       str_locate_chars(&filter_remain_str, "*?{");
+    (*iters)++;
     /* Isolate text leading up to token (if any) - needs to be matched */
     if (locate_result.found)
     {
@@ -311,7 +316,8 @@
         {
           str_copy(&new_filter_str, &brace_list_str);
           str_append_str(&new_filter_str, &filter_remain_str);
-          if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str))
+          if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str,
+                                         iters))
           {
             ret = 1;
             goto out;
@@ -347,6 +353,9 @@
   }
   /* OK, a match */
   ret = 1;
+  if (*iters == VSFTP_MATCHITERS_MAX) {
+    ret = 0;
+  }
 out:
   str_free(&filter_remain_str);
   str_free(&name_remain_str);
Index: vsftpd-2.0.7/ls.h
===================================================================
--- vsftpd-2.0.7.orig/ls.h	2008-02-02 02:30:41.000000000 +0100
+++ vsftpd-2.0.7/ls.h	2011-03-07 15:47:30.974488386 +0100
@@ -35,11 +35,14 @@
  * PARAMETERS
  * p_filename_str  - the filename to match
  * p_filter_str    - the filter to match against
+ * iters           - pointer to a zero-seeded int which prevents the match
+ *                   loop from running an excessive number of times
  * RETURNS
  * Returns 1 if there is a match, 0 otherwise.
  */
 int vsf_filename_passes_filter(const struct mystr* p_filename_str,
-                               const struct mystr* p_filter_str);
+                               const struct mystr* p_filter_str,
+                               unsigned int* iters);
 
 #endif /* VSF_LS_H */
 
Index: vsftpd-2.0.7/sysutil.c
===================================================================
--- vsftpd-2.0.7.orig/sysutil.c	2011-03-07 15:47:09.000000000 +0100
+++ vsftpd-2.0.7/sysutil.c	2011-03-07 15:47:30.991489054 +0100
@@ -1976,7 +1976,7 @@
     static struct vsf_sysutil_sockaddr* s_p_sockaddr;
     vsf_sysutil_sockaddr_alloc_ipv4(&s_p_sockaddr);
     vsf_sysutil_memcpy(&s_p_sockaddr->u.u_sockaddr_in.sin_addr, p_raw,
-                       sizeof(&s_p_sockaddr->u.u_sockaddr_in.sin_addr));
+                       sizeof(s_p_sockaddr->u.u_sockaddr_in.sin_addr));
     vsf_sysutil_memcpy(&p_sockptr->u.u_sockaddr_in6.sin6_addr,
                        vsf_sysutil_sockaddr_ipv4_v6(s_p_sockaddr),
                        sizeof(p_sockptr->u.u_sockaddr_in6.sin6_addr));
