File vsftpd-2.0.6-write_race.patch of Package vsftpd

--- postlogin.c
+++ postlogin.c
@@ -983,6 +983,7 @@
   int remote_fd;
   int success = 0;
   int created = 0;
+  int truncit = 0;
   filesize_t offset = p_sess->restart_pos;
   p_sess->restart_pos = 0;
   if (!data_transfer_checks_ok(p_sess))
@@ -1017,7 +1018,15 @@
     /* For non-anonymous, allow open() to overwrite or append existing files */
     if (!is_append && offset == 0)
     {
-      new_file_fd = str_create_overwrite(p_filename);
+      if (tunable_lock_upload_files)
+      {
+        new_file_fd = str_create_append(p_filename);
+        truncit = 1;
+      }
+      else
+      {
+        new_file_fd = str_create_overwrite(p_filename);
+      }
     }
     else
     {
@@ -1060,6 +1069,11 @@
   if (tunable_lock_upload_files)
   {
     vsf_sysutil_lock_file_write(new_file_fd);
+    if (truncit)
+    {
+      vsf_sysutil_truncate(new_file_fd, 0);
+      vsf_sysutil_lseek_to(new_file_fd, 0);
+    }
   }
   if (!is_append && offset != 0)
   {
--- sysutil.c
+++ sysutil.c
@@ -1200,6 +1200,12 @@
 }
 
 int
+vsf_sysutil_truncate(int fd, filesize_t length)
+{
+  return ftruncate(fd, length);
+}
+
+int
 vsf_sysutil_unlink(const char* p_dead)
 {
   return unlink(p_dead);
--- sysutil.h
+++ sysutil.h
@@ -90,6 +90,8 @@
 int vsf_sysutil_close_failok(int fd);
 int vsf_sysutil_unlink(const char* p_dead);
 int vsf_sysutil_write_access(const char* p_filename);
+/* Trucate after open */
+int vsf_sysutil_truncate(int fd, filesize_t length);
 
 /* Reading and writing */
 void vsf_sysutil_lseek_to(const int fd, filesize_t seek_pos);
openSUSE Build Service is sponsored by