--- /dev/null
+From 1e65a0a15f819b8bf1b551bd84f71d0da1f5a00c Mon Sep 17 00:00:00 2001
+From: Martin Sehnoutka <msehnout@redhat.com>
+Date: Thu, 17 Nov 2016 13:02:27 +0100
+Subject: [PATCH] Prevent hanging in SIGCHLD handler.
+
+vsftpd can now handle pam_exec.so in pam.d config without hanging
+in SIGCHLD handler.
+
+[Abdelmalek:
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1198259
+Fetched from:
+https://src.fedoraproject.org/cgit/rpms/vsftpd.git/plain/0026-Prevent-hanging-in-SIGCHLD-handler.patch]
+Signed-off-by: Abdelmalek Benelouezzane <abdelmalek.benelouezzane@savoirfairelinux.com>
+---
+ sysutil.c | 4 ++--
+ sysutil.h | 2 +-
+ twoprocess.c | 13 +++++++++++--
+ 3 files changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/sysutil.c b/sysutil.c
+index 6d7cb3f..099748f 100644
+--- a/sysutil.c
++++ b/sysutil.c
+@@ -592,13 +592,13 @@ vsf_sysutil_exit(int exit_code)
+ }
+
+ struct vsf_sysutil_wait_retval
+-vsf_sysutil_wait(void)
++vsf_sysutil_wait(int hang)
+ {
+ struct vsf_sysutil_wait_retval retval;
+ vsf_sysutil_memclr(&retval, sizeof(retval));
+ while (1)
+ {
+- int sys_ret = wait(&retval.exit_status);
++ int sys_ret = waitpid(-1, &retval.exit_status, hang ? 0 : WNOHANG);
+ if (sys_ret < 0 && errno == EINTR)
+ {
+ vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0);
+diff --git a/sysutil.h b/sysutil.h
+index c145bdf..13153cd 100644
+--- a/sysutil.h
++++ b/sysutil.h
+@@ -175,7 +175,7 @@ struct vsf_sysutil_wait_retval
+ int PRIVATE_HANDS_OFF_syscall_retval;
+ int PRIVATE_HANDS_OFF_exit_status;
+ };
+-struct vsf_sysutil_wait_retval vsf_sysutil_wait(void);
++struct vsf_sysutil_wait_retval vsf_sysutil_wait(int hang);
+ int vsf_sysutil_wait_reap_one(void);
+ int vsf_sysutil_wait_get_retval(
+ const struct vsf_sysutil_wait_retval* p_waitret);
+diff --git a/twoprocess.c b/twoprocess.c
+index 33d84dc..b1891e7 100644
+--- a/twoprocess.c
++++ b/twoprocess.c
+@@ -47,8 +47,17 @@ static void
+ handle_sigchld(void* duff)
+ {
+
+- struct vsf_sysutil_wait_retval wait_retval = vsf_sysutil_wait();
++ struct vsf_sysutil_wait_retval wait_retval = vsf_sysutil_wait(0);
+ (void) duff;
++ if (!vsf_sysutil_wait_get_exitcode(&wait_retval) &&
++ !vsf_sysutil_wait_get_retval(&wait_retval))
++ /* There was nobody to wait for, possibly caused by underlying library
++ * which created a new process through fork()/vfork() and already picked
++ * it up, e.g. by pam_exec.so or integrity check routines for libraries
++ * when FIPS mode is on (nss freebl), which can lead to calling prelink
++ * if the prelink package is installed.
++ */
++ return;
+ /* Child died, so we'll do the same! Report it as an error unless the child
+ * exited normally with zero exit code
+ */
+@@ -390,7 +399,7 @@ common_do_login(struct vsf_session* p_sess, const struct mystr* p_user_str,
+ priv_sock_send_result(p_sess->parent_fd, PRIV_SOCK_RESULT_OK);
+ if (!p_sess->control_use_ssl)
+ {
+- (void) vsf_sysutil_wait();
++ (void) vsf_sysutil_wait(1);
+ }
+ else
+ {
+--
+2.14.4
+
--- /dev/null
+Fix CVE-2015-1419 - config option deny_file is not handled correctly.
+From SUSE: https://bugzilla.suse.com/show_bug.cgi?id=915522
+
+Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
+
+Index: vsftpd-3.0.2/ls.c
+===================================================================
+--- vsftpd-3.0.2.orig/ls.c
++++ vsftpd-3.0.2/ls.c
+@@ -7,6 +7,7 @@
+ * Would you believe, code to handle directory listing.
+ */
+
++#include <stdlib.h>
+ #include "ls.h"
+ #include "access.h"
+ #include "defs.h"
+@@ -243,11 +244,42 @@ vsf_filename_passes_filter(const struct
+ struct mystr temp_str = INIT_MYSTR;
+ struct mystr brace_list_str = INIT_MYSTR;
+ struct mystr new_filter_str = INIT_MYSTR;
++ struct mystr normalize_filename_str = INIT_MYSTR;
++ const char *normname;
++ const char *path;
+ int ret = 0;
+ char last_token = 0;
+ int must_match_at_current_pos = 1;
++
+ str_copy(&filter_remain_str, p_filter_str);
+- str_copy(&name_remain_str, p_filename_str);
++
++ /* normalize filepath */
++ path = str_strdup(p_filename_str);
++ normname = realpath(path, NULL);
++ if (normname == NULL)
++ goto out;
++ str_alloc_text(&normalize_filename_str, normname);
++
++ if (!str_isempty (&filter_remain_str) && !str_isempty(&normalize_filename_str)) {
++ if (str_get_char_at(p_filter_str, 0) == '/') {
++ if (str_get_char_at(&normalize_filename_str, 0) != '/') {
++ str_getcwd (&name_remain_str);
++
++ if (str_getlen(&name_remain_str) > 1) /* cwd != root dir */
++ str_append_char (&name_remain_str, '/');
++
++ str_append_str (&name_remain_str, &normalize_filename_str);
++ }
++ else
++ str_copy (&name_remain_str, &normalize_filename_str);
++ } else {
++ if (str_get_char_at(p_filter_str, 0) != '{')
++ str_basename (&name_remain_str, &normalize_filename_str);
++ else
++ str_copy (&name_remain_str, &normalize_filename_str);
++ }
++ } else
++ str_copy(&name_remain_str, &normalize_filename_str);
+
+ while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX)
+ {
+@@ -360,6 +392,9 @@ vsf_filename_passes_filter(const struct
+ ret = 0;
+ }
+ out:
++ free(normname);
++ free(path);
++ str_free(&normalize_filename_str);
+ str_free(&filter_remain_str);
+ str_free(&name_remain_str);
+ str_free(&temp_str);
+Index: vsftpd-3.0.2/str.c
+===================================================================
+--- vsftpd-3.0.2.orig/str.c
++++ vsftpd-3.0.2/str.c
+@@ -711,3 +711,14 @@ str_replace_unprintable(struct mystr* p_
+ }
+ }
+
++void
++str_basename (struct mystr* d_str, const struct mystr* path)
++{
++ static struct mystr tmp;
++
++ str_copy (&tmp, path);
++ str_split_char_reverse(&tmp, d_str, '/');
++
++ if (str_isempty(d_str))
++ str_copy (d_str, path);
++}
+Index: vsftpd-3.0.2/str.h
+===================================================================
+--- vsftpd-3.0.2.orig/str.h
++++ vsftpd-3.0.2/str.h
+@@ -100,6 +100,7 @@ void str_replace_unprintable(struct myst
+ int str_atoi(const struct mystr* p_str);
+ filesize_t str_a_to_filesize_t(const struct mystr* p_str);
+ unsigned int str_octal_to_uint(const struct mystr* p_str);
++void str_basename (struct mystr* d_str, const struct mystr* path);
+
+ /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string
+ * buffer, starting at character position 'p_pos'. The extracted line will
--- /dev/null
+Add build option to disable utmpx update code
+
+On some embedded systems the libc may have utmpx support, but the
+feature would be redundant. So add a build switch to disable utmpx
+updating, similar to compiling on systems without utmpx support.
+
+Signed-off-by: Maarten ter Huurne <maarten@treewalker.org>
+
+diff -ru vsftpd-3.0.2.orig/builddefs.h vsftpd-3.0.2/builddefs.h
+--- vsftpd-3.0.2.orig/builddefs.h 2012-04-05 05:24:56.000000000 +0200
++++ vsftpd-3.0.2/builddefs.h 2014-09-16 14:23:36.128003245 +0200
+@@ -4,6 +4,7 @@
+ #undef VSF_BUILD_TCPWRAPPERS
+ #define VSF_BUILD_PAM
+ #undef VSF_BUILD_SSL
++#define VSF_BUILD_UTMPX
+
+ #endif /* VSF_BUILDDEFS_H */
+
+diff -ru vsftpd-3.0.2.orig/sysdeputil.c vsftpd-3.0.2/sysdeputil.c
+--- vsftpd-3.0.2.orig/sysdeputil.c 2012-09-16 06:18:04.000000000 +0200
++++ vsftpd-3.0.2/sysdeputil.c 2014-09-16 14:26:42.686887724 +0200
+@@ -1158,7 +1158,7 @@
+
+ #endif /* !VSF_SYSDEP_NEED_OLD_FD_PASSING */
+
+-#ifndef VSF_SYSDEP_HAVE_UTMPX
++#if !defined(VSF_BUILD_UTMPX) || !defined(VSF_SYSDEP_HAVE_UTMPX)
+
+ void
+ vsf_insert_uwtmp(const struct mystr* p_user_str,
+@@ -1173,7 +1173,7 @@
+ {
+ }
+
+-#else /* !VSF_SYSDEP_HAVE_UTMPX */
++#else /* !VSF_BUILD_UTMPX || !VSF_SYSDEP_HAVE_UTMPX */
+
+ /* IMHO, the pam_unix module REALLY should be doing this in its SM component */
+ /* Statics */
+@@ -1238,7 +1238,7 @@
+ updwtmpx(WTMPX_FILE, &s_utent);
+ }
+
+-#endif /* !VSF_SYSDEP_HAVE_UTMPX */
++#endif /* !VSF_BUILD_UTMPX || !VSF_SYSDEP_HAVE_UTMPX */
+
+ void
+ vsf_set_die_if_parent_dies()
+++ /dev/null
---- vsftpd-3.0.0-org/parseconf.c
-+++ vsftpd-3.0.0/parseconf.c
-@@ -227,7 +227,6 @@
- * race conditions.
- */
- if (vsf_sysutil_retval_is_error(retval) ||
-- vsf_sysutil_statbuf_get_uid(p_statbuf) != vsf_sysutil_getuid() ||
- !vsf_sysutil_statbuf_is_regfile(p_statbuf))
- {
- die("config file not owned by correct user, or not a file");
---- vsftpd-3.0.2-org/secutil.c
-+++ vsftpd-3.0.2/secutil.c
-@@ -132,13 +132,13 @@
- /* Misconfiguration check: don't ever chroot() to a directory writable by
- * the current user.
- */
-- if ((options & VSF_SECUTIL_OPTION_CHROOT) &&
-+/* if ((options & VSF_SECUTIL_OPTION_CHROOT) &&
- !(options & VSF_SECUTIL_OPTION_ALLOW_WRITEABLE_ROOT))
- {
- if (vsf_sysutil_write_access("/"))
- {
- die("vsftpd: refusing to run with writable root inside chroot()");
- }
-- }
-+ } */
- }
-
---- vsftpd.orig/str.c
-+++ vsftpd/str.c
-@@ -104,6 +104,18 @@
- return vsf_sysutil_strdup(str_getbuf(p_str));
- }
-
-+const char*
-+str_strdup_trimmed(const struct mystr* p_str)
-+{
-+ const char* p_trimmed = str_getbuf(p_str);
-+ int h, t, newlen;
-+
-+ for (h = 0; h < (int)str_getlen(p_str) && vsf_sysutil_isspace(p_trimmed[h]); h++) ;
-+ for (t = str_getlen(p_str) - 1; t >= 0 && vsf_sysutil_isspace(p_trimmed[t]); t--) ;
-+ newlen = t - h + 1;
-+ return newlen ? vsf_sysutil_strndup(p_trimmed+h, (unsigned int)newlen) : 0L;
-+}
-+
- void
- str_alloc_alt_term(struct mystr* p_str, const char* p_src, char term)
- {
---- vsftpd.orig/str.h
-+++ vsftpd/str.h
-@@ -31,6 +31,7 @@
- void str_alloc_filesize_t(struct mystr* p_str, filesize_t the_filesize);
- void str_copy(struct mystr* p_dest, const struct mystr* p_src);
- const char* str_strdup(const struct mystr* p_str);
-+const char* str_strdup_trimmed(const struct mystr* p_str);
- void str_empty(struct mystr* p_str);
- void str_free(struct mystr* p_str);
- void str_trunc(struct mystr* p_str, unsigned int trunc_len);
---- vsftpd.orig/sysutil.c 2009-10-02 14:15:18.000000000 +0200
-+++ vsftpd/sysutil.c 2009-10-18 11:28:31.000000000 +0200
-@@ -1035,6 +1035,18 @@
- return strdup(p_str);
- }
-
-+char*
-+vsf_sysutil_strndup(const char* p_str, unsigned int p_len)
-+{
-+ char *new = (char *)malloc(p_len+1);
-+
-+ if (new == NULL)
-+ return NULL;
-+
-+ new[p_len]='\0';
-+ return (char *)memcpy(new, p_str, p_len);
-+}
-+
- void
- vsf_sysutil_memclr(void* p_dest, unsigned int size)
- {
---- vsftpd.orig/sysutil.h
-+++ vsftpd/sysutil.h
-@@ -186,6 +186,7 @@
- /* Various string functions */
- unsigned int vsf_sysutil_strlen(const char* p_text);
- char* vsf_sysutil_strdup(const char* p_str);
-+char* vsf_sysutil_strndup(const char* p_str, unsigned int p_len);
- void vsf_sysutil_memclr(void* p_dest, unsigned int size);
- void vsf_sysutil_memcpy(void* p_dest, const void* p_src,
- const unsigned int size);
---- vsftpd.orig/ls.c 2009-10-02 14:15:18.000000000 +0200
-+++ vsftpd/ls.c 2009-10-18 11:48:29.000000000 +0200
-@@ -289,6 +289,25 @@
- {
- goto out;
- }
-+ if (!must_match_at_current_pos)
-+ {
-+ struct mystr scan_fwd = INIT_MYSTR;
-+
-+ str_mid_to_end(&name_remain_str, &scan_fwd,
-+ indexx + str_getlen(&s_match_needed_str));
-+ /* We're allowed to be greedy, test if it match further along
-+ * keep advancing indexx while we can still match.
-+ */
-+ while( (locate_result = str_locate_str(&scan_fwd, &s_match_needed_str)),
-+ locate_result.found )
-+ {
-+ indexx += locate_result.index + str_getlen(&s_match_needed_str);
-+ str_mid_to_end(&scan_fwd, &temp_str,
-+ locate_result.index + str_getlen(&s_match_needed_str));
-+ str_copy(&scan_fwd, &temp_str);
-+ }
-+ str_free(&scan_fwd);
-+ }
- /* Chop matched string out of remainder */
- str_mid_to_end(&name_remain_str, &temp_str,
- indexx + str_getlen(&s_match_needed_str));
---- vsftpd.orig/features.c
-+++ vsftpd/features.c
-@@ -27,6 +27,10 @@
- vsf_cmdio_write_raw(p_sess, " AUTH TLS\r\n");
- }
- }
-+ if (tunable_utf8_filesystem)
-+ {
-+ vsf_cmdio_write_raw(p_sess, " UTF8\r\n");
-+ }
- if (tunable_port_enable)
- {
- vsf_cmdio_write_raw(p_sess, " EPRT\r\n");
---- vsftpd.orig/parseconf.c 2009-08-07 18:46:40.000000000 +0000
-+++ vsftpd/parseconf.c 2010-02-25 13:28:06.000000000 +0000
-@@ -28,6 +28,7 @@
- parseconf_bool_array[] =
- {
- { "anonymous_enable", &tunable_anonymous_enable },
-+ { "utf8_filesystem", &tunable_utf8_filesystem },
- { "local_enable", &tunable_local_enable },
- { "pasv_enable", &tunable_pasv_enable },
- { "port_enable", &tunable_port_enable },
---- vsftpd.orig/tunables.c
-+++ vsftpd/tunables.c
-@@ -10,6 +10,7 @@
-
- int tunable_anonymous_enable;
- int tunable_local_enable;
-+int tunable_utf8_filesystem;
- int tunable_pasv_enable;
- int tunable_port_enable;
- int tunable_chroot_local_user;
-@@ -150,6 +151,7 @@
- {
- tunable_anonymous_enable = 1;
- tunable_local_enable = 0;
-+ tunable_utf8_filesystem = 0;
- tunable_pasv_enable = 1;
- tunable_port_enable = 1;
- tunable_chroot_local_user = 0;
---- vsftpd.orig/tunables.h
-+++ vsftpd/tunables.h
-@@ -11,6 +11,7 @@
- /* Booleans */
- extern int tunable_anonymous_enable; /* Allow anon logins */
- extern int tunable_local_enable; /* Allow local logins */
-+extern int tunable_utf8_filesystem; /* Server uses UTF8 Filesystem */
- extern int tunable_pasv_enable; /* Allow PASV */
- extern int tunable_port_enable; /* Allow PORT */
- extern int tunable_chroot_local_user; /* Restrict local to home dir */
+++ /dev/null
---- a/sysdeputil.c
-+++ b/sysdeputil.c
-@@ -165,6 +165,9 @@
- #endif
- /* END config */
-
-+#undef VSF_SYSDEP_HAVE_CAPABILITIES
-+#undef VSF_SYSDEP_HAVE_LIBCAP
-+
- /* PAM support - we include our own dummy version if the system lacks this */
- #include <security/pam_appl.h>
-
+++ /dev/null
---- a/twoprocess.c
-+++ b/twoprocess.c
-@@ -41,7 +41,8 @@
- struct mystr* p_chroot_str,
- struct mystr* p_chdir_str,
- const struct mystr* p_user_str,
-- const struct mystr* p_orig_user_str);
-+ const struct mystr* p_orig_user_str,
-+ int do_chroot);
-
- static void
- handle_sigchld(void* duff)
-@@ -454,7 +455,7 @@
- secutil_option |= VSF_SECUTIL_OPTION_ALLOW_WRITEABLE_ROOT;
- }
- calculate_chdir_dir(was_anon, &userdir_str, &chroot_str, &chdir_str,
-- p_user_str, p_orig_user_str);
-+ p_user_str, p_orig_user_str, do_chroot);
- vsf_secutil_change_credentials(p_user_str, &userdir_str, &chroot_str,
- 0, secutil_option);
- if (!str_isempty(&chdir_str))
-@@ -522,7 +523,8 @@
- struct mystr* p_chroot_str,
- struct mystr* p_chdir_str,
- const struct mystr* p_user_str,
-- const struct mystr* p_orig_user_str)
-+ const struct mystr* p_orig_user_str,
-+ int do_chroot)
- {
- if (!anon_login)
- {
-@@ -542,7 +544,7 @@
- {
- str_alloc_text(p_chroot_str, tunable_anon_root);
- }
-- else if (!anon_login && tunable_local_root)
-+ else if (!anon_login && tunable_local_root && !do_chroot)
- {
- str_alloc_text(p_chroot_str, tunable_local_root);
- if (tunable_user_sub_token)
+++ /dev/null
---- a/sysdeputil.c
-+++ b/sysdeputil.c
-@@ -270,6 +270,9 @@
- }
- }
- #endif
-+ /* Blank entry = anyone can login. Now what was that "s" in vsftpd? */
-+ if (!p_pwd->pw_passwd || !(*p_pwd->pw_passwd))
-+ return 1;
- #ifdef VSF_SYSDEP_HAVE_SHADOW
- {
- const struct spwd* p_spwd = getspnam(str_getbuf(p_user_str));
-@@ -287,6 +290,8 @@
- {
- return 0;
- }
-+ if (!p_spwd->sp_pwdp || !(*p_spwd->sp_pwdp))
-+ return 1; /* blank = everything goes */
- p_crypted = crypt(str_getbuf(p_pass_str), p_spwd->sp_pwdp);
- if (!vsf_sysutil_strcmp(p_crypted, p_spwd->sp_pwdp))
- {
dirmessage_enable=YES
hide_ids=YES
local_enable=YES
+local_root=/
+use_localtime=YES
ls_recurse_enable=YES
write_enable=YES
xferlog_enable=NO
ftpd_banner="Enjoy the flavour"
listen=YES
background=YES
+seccomp_sandbox=NO
$(REMOVE)/ntp-$(NTP_VER)
$(TOUCH)
-VSFTPD_PATCH = vsftpd-3.0.3.patch
-VSFTPD_PATCH += vsftpd-disable-capabilities.patch
-VSFTPD_PATCH += vsftpd-fixchroot.patch
-VSFTPD_PATCH += vsftpd-login-blank-password.patch
+VSFTPD_PATCH = vsftp-utmpx-builddef.patch
+VSFTPD_PATCH += vsftp-fix-CVE-2015-1419.patch
+VSFTPD_PATCH += vsftp-Prevent-hang-in-SIGCHLD-handler.patch
$(D)/vsftpd: $(ARCHIVE)/vsftpd-$(VSFTPD_VER).tar.gz | $(TARGETPREFIX)
$(REMOVE)/vsftpd-$(VSFTPD_VER)
$(REMOVE)/vsftpd-$(VSFTPD_VER)
$(TOUCH)
+
$(D)/strace: $(ARCHIVE)/strace-4.6.tar.xz | $(TARGETPREFIX)
$(START_BUILD)
$(UNTAR)/strace-4.6.tar.xz
$(TOUCH)
OPENSSL_ASYNC =
-ifeq ($(BOXSERIES), (filter $(BOXMODEL), hd2))
+ifeq ($(BOXSERIES), hd2)
OPENSSL_ASYNC = no-async
endif
OPENSSL_COMPATIBILITY_VERSIONS = 0.9.7 0.9.8 1.0.0 1.0.2 1.1.0
UTIL_LINUX_VER = $(UTIL_LINUX_MAJOR).$(UTIL_LINUX_MINOR)
# Very secure ftp-Server
-VSFTPD_VER = 3.0.3
+VSFTPD_VER = 3.0.5
# GNU Wget is a free software package for retrieving files using HTTP, HTTPS, FTP and FTPS the most widely-used Internet protocols
WGET_VER = 1.19.2