File vsftpd-2.0.7-excessive-cpu-usage.patch of Package vsftpd
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));