Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package atftp for openSUSE:Factory checked 
in at 2021-09-25 00:35:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/atftp (Old)
 and      /work/SRC/openSUSE:Factory/.atftp.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "atftp"

Sat Sep 25 00:35:07 2021 rev:41 rq:920601 version:0.7.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/atftp/atftp.changes      2021-06-02 
22:10:30.556127635 +0200
+++ /work/SRC/openSUSE:Factory/.atftp.new.1899/atftp.changes    2021-09-25 
00:35:33.511139660 +0200
@@ -1,0 +2,32 @@
+Wed Sep 15 13:17:41 UTC 2021 - Pedro Monreal <pmonr...@suse.com>
+
+- Update to version 0.7.5 [bsc#1190522, CVE-2021-41054]
+  * text files: mark/convert all textfiles to UTF-8
+  * fix some compiler warnings
+  * fix buffer overflow in atftpd (CVE-2021-41054)
+  * test.sh: check for root no longer necessary
+  * tftpd.c: Only drop privs if requested or running as root + check for 
failure
+  * fix invalid read of 1 byte in tftp_send_request.
+  * Check return value of fseek(), abort if != 0
+  * options.c: Proper fix for the read-past-end-of-array
+  * configure.ac: Add -std=gnu89 if gcc/clang is detected
+  * tftpd.c: Fix memleak if thread spawning fails
+  * atftp: Check return value of fgets, buffer might be uninitialized on NULL
+  * Fix check for argz support (HAVE_ARGZ -> HAVE_ARGZ_H)
+  * replace LICENSE with current version
+  * Remove patches fixed upstream:
+    - atftp-0.7-sorcerers_apprentice.patch
+    - atftp-0.7-server_receive_race.patch
+    - atftp-0.7-ack_heuristic.patch
+  * Rebase patches:
+    - atftp-drop_privileges_non-daemon.patch
+    - atftp-0.7-default_dir_man.patch
+    - atftp-0.7-default_user_man.patch
+
+-------------------------------------------------------------------
+Tue Sep 14 09:57:25 UTC 2021 - Johannes Segitz <jseg...@suse.com>
+
+- Added hardening to systemd service(s) (bsc#1181400). Modified:
+  * atftpd.service
+
+-------------------------------------------------------------------

Old:
----
  atftp-0.7-ack_heuristic.patch
  atftp-0.7-server_receive_race.patch
  atftp-0.7-sorcerers_apprentice.patch
  atftp-0.7.4.tar.gz

New:
----
  atftp-0.7.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ atftp.spec ++++++
--- /var/tmp/diff_new_pack.TBgH6m/_old  2021-09-25 00:35:35.935142190 +0200
+++ /var/tmp/diff_new_pack.TBgH6m/_new  2021-09-25 00:35:35.935142190 +0200
@@ -23,27 +23,21 @@
 %endif
 
 Name:           atftp
-Version:        0.7.4
+Version:        0.7.5
 Release:        0
 Summary:        Advanced TFTP Server and Client
 License:        GPL-2.0-or-later
 Group:          System/Daemons
 URL:            https://sourceforge.net/projects/atftp/
-Source:         %{name}-%{version}.tar.gz
+Source:         
https://sourceforge.net/projects/atftp/files/%{name}-%{version}.tar.gz
 Source2:        atftpd.sysconfig
 Source3:        atftpd.logrotate
 Source5:        atftpd.service
 Source6:        atftpd.socket
-# PATCH-FIX-SUSE sorcerer's apprentice syndrom (bnc#727843)
-Patch1:         atftp-0.7-sorcerers_apprentice.patch
-# PATCH-FIX-SUSE server receive thread race (bnc#599856)
-Patch2:         atftp-0.7-server_receive_race.patch
-# PATCH-FIX-SUSE drop one duplicated ACK each round (bnc#774376)
-Patch3:         atftp-0.7-ack_heuristic.patch
-Patch4:         atftp-0.7-default_user_man.patch
+Patch1:         atftp-0.7-default_user_man.patch
 # PATCH-FIX-SUSE update default directory in man (bnc#507011)
-Patch5:         atftp-0.7-default_dir_man.patch
-Patch6:         atftp-drop_privileges_non-daemon.patch
+Patch2:         atftp-0.7-default_dir_man.patch
+Patch3:         atftp-drop_privileges_non-daemon.patch
 BuildRequires:  autoconf
 BuildRequires:  automake
 BuildRequires:  pcre-devel
@@ -68,13 +62,7 @@
 boot of hundreds of machines simultaneously.
 
 %prep
-%setup -q -n %{name}-%{version}
-%patch1
-%patch2
-%patch3
-%patch4
-%patch5
-%patch6 -p1
+%autosetup -p1
 
 %build
 autoreconf -fi

++++++ atftp-0.7-default_dir_man.patch ++++++
--- /var/tmp/diff_new_pack.TBgH6m/_old  2021-09-25 00:35:35.959142215 +0200
+++ /var/tmp/diff_new_pack.TBgH6m/_new  2021-09-25 00:35:35.959142215 +0200
@@ -1,8 +1,8 @@
-Index: atftpd.8
+Index: atftp-0.7.5/atftpd.8
 ===================================================================
---- atftpd.8.orig
-+++ atftpd.8
-@@ -210,7 +210,7 @@ Show summary of options.
+--- atftp-0.7.5.orig/atftpd.8
++++ atftp-0.7.5/atftpd.8
+@@ -211,7 +211,7 @@ Show summary of options.
  .B path
  This is the root directory used by the TFTP server. All requested
  files from a TFTP client must reside in this directory. If not

++++++ atftp-0.7-default_user_man.patch ++++++
--- /var/tmp/diff_new_pack.TBgH6m/_old  2021-09-25 00:35:35.967142223 +0200
+++ /var/tmp/diff_new_pack.TBgH6m/_new  2021-09-25 00:35:35.967142223 +0200
@@ -1,7 +1,7 @@
-Index: atftpd.8
+Index: atftp-0.7.5/atftpd.8
 ===================================================================
---- atftpd.8.orig
-+++ atftpd.8
+--- atftp-0.7.5.orig/atftpd.8
++++ atftp-0.7.5/atftpd.8
 @@ -80,10 +80,10 @@ acknowledging the 'multicast' request by
  
  .TP

++++++ atftp-0.7.4.tar.gz -> atftp-0.7.5.tar.gz ++++++
++++ 6686 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/BUGS new/atftp-0.7.5/BUGS
--- old/atftp-0.7.4/BUGS        2011-03-11 07:51:24.000000000 +0100
+++ new/atftp-0.7.5/BUGS        2021-09-13 21:45:03.000000000 +0200
@@ -1,4 +1,4 @@
-If you find some bugs, please send us a detailed description of the
+???If you find some bugs, please send us a detailed description of the
 problem observed. Please include the logfile and a full description of
 your setup.
 
@@ -9,4 +9,4 @@
 (10Mbit, 100Mbit or 1Gbit).
 
 Jean-Pierre Lefebvre <he...@step.polymtl.ca>
-Remi Lefebvre <r...@step.polymtl.ca>
\ No newline at end of file
+Remi Lefebvre <r...@step.polymtl.ca>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/Changelog new/atftp-0.7.5/Changelog
--- old/atftp-0.7.4/Changelog   2021-02-02 00:59:12.000000000 +0100
+++ new/atftp-0.7.5/Changelog   2021-09-14 00:23:36.000000000 +0200
@@ -1,3 +1,29 @@
+???atftp-0.7.5
+===========
+e3dfc46 N - Martin Dummer / README: update contributors list
+694f872 N - Martin Dummer / text files: mark/convert all textfiles to UTF-8
+48939af N - Martin Dummer / fix some compiler warnings
+d255bf9 N - Martin Dummer / fix buffer overflow in atftpd (CVE-2021-41054)
+a8190d2 N - Martin Dummer / insert typos.patch
+f04cab8 N - Martin Dummer / insert atftp-0.7-ack_heuristic.patch
+8dce19d N - Martin Dummer / insert atftp-0.7-server_receive_race.patch
+127bc42 N - Martin Dummer / insert patch atftp-0.7-sorcerers_apprentice.patch
+c546e94 N - Martin Dummer / test.sh: check for root no longer necessary
+
+Merge commits from https://github.com/srett/atftp
+=================================================
+313e010 N - Simon Rettberg / tftpd.c: Only drop privs if requested or running 
as root + check for failure
+c5f4236 N - Simon Rettberg / fix invalid read of 1 byte in tftp_send_request.
+cef874a N - Simon Rettberg / Check return value of fseek(), abort if != 0
+10bfe5f N - Simon Rettberg / options.c: Proper fix for the 
read-past-end-of-array
+4db65ee N - Simon Rettberg / configure.ac: Add -std=gnu89 if gcc/clang is 
detected
+5471a07 N - Simon Rettberg / tftpd.c: Fix memleak if thread spawning fails
+7ab8575 N - Simon Rettberg / atftp: Check return value of fgets, buffer might 
be uninitialized on NULL
+d8390a1 N - Simon Rettberg / Fix check for argz support (HAVE_ARGZ -> 
HAVE_ARGZ_H)
+
+bf22cca N - Martin Dummer / replace LICENSE with current version
+
+
 atftp-0.7.4
 ===========
 4f2f95c N - Martin Dummer / test.sh: rework test script
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/FAQ new/atftp-0.7.5/FAQ
--- old/atftp-0.7.4/FAQ 2011-03-11 07:51:24.000000000 +0100
+++ new/atftp-0.7.5/FAQ 2021-09-13 21:47:55.000000000 +0200
@@ -1,4 +1,4 @@
-1) What are the best values for --tftpd-timeout, --retry-timeout and
+???1) What are the best values for --tftpd-timeout, --retry-timeout and
     --max-thread ?
 
 There is no absolute answer to that question. It is highly dependent
@@ -6,7 +6,7 @@
 how to tune them.
 
 --tftpd-timeout controls how much time the server will wait for an
-incomming connection before killing the main thread. If you use small
+incoming connection before killing the main thread. If you use small
 number, the server will be respawned by inetd when a new query
 arrives. If number is high, atftpd will behave more like a standalone
 server in that it will always receive queries directly. When booting a
@@ -124,4 +124,4 @@
 }
 
 This is the basic stuff. Read inetd or xinetd man page for more specialised
-configuration.
\ No newline at end of file
+configuration.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/INSTALL new/atftp-0.7.5/INSTALL
--- old/atftp-0.7.4/INSTALL     2012-08-02 00:21:51.000000000 +0200
+++ new/atftp-0.7.5/INSTALL     2021-09-13 22:04:48.000000000 +0200
@@ -1,4 +1,4 @@
-The simplest way to install atftp is using either the Debian package
+???The simplest way to install atftp is using either the Debian package
 or one provided by your distribution if any. If you need to install
 atftp from source, here's the procedure.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/LICENSE new/atftp-0.7.5/LICENSE
--- old/atftp-0.7.4/LICENSE     2011-03-11 07:51:24.000000000 +0100
+++ new/atftp-0.7.5/LICENSE     2021-06-29 14:22:40.000000000 +0200
@@ -1,12 +1,12 @@
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
 
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-                           Preamble
+                            Preamble
 
   The licenses for most software are designed to take away your
 freedom to share and change it.  By contrast, the GNU General Public
@@ -15,7 +15,7 @@
 General Public License applies to most of the Free Software
 Foundation's software and to any other program whose authors commit to
 using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
+the GNU Lesser General Public License instead.)  You can apply it to
 your programs, too.
 
   When we speak of free software, we are referring to freedom, not
@@ -56,7 +56,7 @@
   The precise terms and conditions for copying, distribution and
 modification follow.
 
-                   GNU GENERAL PUBLIC LICENSE
+                    GNU GENERAL PUBLIC LICENSE
    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
   0. This License applies to any program or other work which contains
@@ -110,7 +110,7 @@
     License.  (Exception: if the Program itself is interactive but
     does not normally print such an announcement, your work based on
     the Program is not required to print an announcement.)
-
+
 These requirements apply to the modified work as a whole.  If
 identifiable sections of that work are not derived from the Program,
 and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@
 access to copy the source code from the same place counts as
 distribution of the source code, even though third parties are not
 compelled to copy the source along with the object code.
-
+
   4. You may not copy, modify, sublicense, or distribute the Program
 except as expressly provided under this License.  Any attempt
 otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@
 
 This section is intended to make thoroughly clear what is believed to
 be a consequence of the rest of this License.
-
+
   8. If the distribution and/or use of the Program is restricted in
 certain countries either by patents or by copyrighted interfaces, the
 original copyright holder who places the Program under this License
@@ -255,7 +255,7 @@
 of preserving the free status of all derivatives of our free software and
 of promoting the sharing and reuse of software generally.
 
-                           NO WARRANTY
+                            NO WARRANTY
 
   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
@@ -277,9 +277,9 @@
 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGES.
 
-                    END OF TERMS AND CONDITIONS
+                     END OF TERMS AND CONDITIONS
 
-           How to Apply These Terms to Your New Programs
+            How to Apply These Terms to Your New Programs
 
   If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
@@ -303,17 +303,16 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 Also add information on how to contact you by electronic and paper mail.
 
 If the program is interactive, make it output a short notice like this
 when it starts in an interactive mode:
 
-    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision version 69, Copyright (C) year name of author
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@
 This General Public License does not permit incorporating your program into
 proprietary programs.  If your program is a subroutine library, you may
 consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
+library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/README new/atftp-0.7.5/README
--- old/atftp-0.7.4/README      2012-07-19 08:22:48.000000000 +0200
+++ new/atftp-0.7.5/README      2021-09-13 22:18:21.000000000 +0200
@@ -1,4 +1,4 @@
-    Jean-Pierre Lefebvre <he...@step.polymtl.ca>
+???    Jean-Pierre Lefebvre <he...@step.polymtl.ca>
     August 20th, 2000
     -----------------
 
@@ -47,3 +47,12 @@
 Thomas Anders          <thomas.and...@blue-cable.de>
 Micha?? Rzechonek      <m.rzecho...@kelvatek.com>
 Florian Fainelli       <f.faine...@gmail.com>
+Denis Andzakovic        <denis.andzako...@pulsesecurity.co.nz>
+Rosen Penev             <ros...@gmail.com>
+Peter Kaestle           <peter.kaes...@nokia.com>
+Grant Edwards
+Ryan Barnett            <ryan.barn...@rockwellcollins.com>
+Peter Seiderer          <ps.rep...@gmx.net>
+Simon Rettberg          <simon.rettb...@rz.uni-freiburg.de>
+Andreas B. Mundt        <a...@debian.org>
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/README.CVS new/atftp-0.7.5/README.CVS
--- old/atftp-0.7.4/README.CVS  2012-08-01 06:58:04.000000000 +0200
+++ new/atftp-0.7.5/README.CVS  2021-09-13 22:19:48.000000000 +0200
@@ -1,4 +1,4 @@
-atftp-0.7.1 and later
+???atftp-0.7.1 and later
 =====================
 
 Development of atftp has switched over to a sourceforge project. 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/README.MCAST new/atftp-0.7.5/README.MCAST
--- old/atftp-0.7.4/README.MCAST        2012-08-01 07:04:34.000000000 +0200
+++ new/atftp-0.7.5/README.MCAST        2021-09-13 22:20:08.000000000 +0200
@@ -1,4 +1,4 @@
-Atftp supports multicast transfer. This feature allows the server to
+???Atftp supports multicast transfer. This feature allows the server to
 send a file to many clients at once. There are two ways of doing
 multicast TFTP. One is documented in RFC2090 and the other is known
 as MTFTP and documented in Intel's PXE specification. Atftp supports
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/README.PCRE new/atftp-0.7.5/README.PCRE
--- old/atftp-0.7.4/README.PCRE 2012-08-01 07:06:06.000000000 +0200
+++ new/atftp-0.7.5/README.PCRE 2021-09-13 22:20:27.000000000 +0200
@@ -1,4 +1,4 @@
-File name mangling with PCRE in atftpd
+???File name mangling with PCRE in atftpd
 ======================================
 
 Here is an attempt at using PCRE (Perl Compatible Regular Expressions)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/TODO new/atftp-0.7.5/TODO
--- old/atftp-0.7.4/TODO        2011-03-11 07:51:24.000000000 +0100
+++ new/atftp-0.7.5/TODO        2021-09-13 22:20:44.000000000 +0200
@@ -1,4 +1,4 @@
-Client
+???Client
 ------
 
 Server
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/argz.c new/atftp-0.7.5/argz.c
--- old/atftp-0.7.4/argz.c      2011-03-11 07:51:24.000000000 +0100
+++ new/atftp-0.7.5/argz.c      2021-09-12 13:12:30.000000000 +0200
@@ -17,7 +17,9 @@
  *
  */
 
-#ifndef HAVE_ARGZ
+#include "config.h"
+
+#ifndef HAVE_ARGZ_H
 
 /* Routines for dealing with '\0' separated arg vectors.
    Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/atftp.1 new/atftp-0.7.5/atftp.1
--- old/atftp-0.7.4/atftp.1     2012-08-20 17:36:31.000000000 +0200
+++ new/atftp-0.7.5/atftp.1     2021-09-13 00:14:14.000000000 +0200
@@ -88,6 +88,14 @@
 See atftpd's man page.
 
 .TP
+.B \-\-prevent\-sas
+Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350.
+This RFC requires repeated responses to a single packet to be
+rejected. Thus a block will only get retransmitted on a timeout.
+For backward compatibility, the default stays to ignore this RFC.
+So blocks get transmitted on every request.
+
+.TP
 .B \-\-verbose
 Instruct atftp to be verbose. It will print more information about
 what's going on.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/atftpd.8 new/atftp-0.7.5/atftpd.8
--- old/atftp-0.7.4/atftpd.8    2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/atftpd.8    2021-09-13 00:14:14.000000000 +0200
@@ -20,7 +20,7 @@
 .SH DESCRIPTION
 .B atftpd
 is a TFTP (RFC1350) server. By default it is started by inetd on most
-sytems, but may run as a stand alone daemon. This server is
+systems, but may run as a stand alone daemon. This server is
 multi-threaded and supports all options described in RFC2347 (option
 extension), RFC2348 (blksize), RFC2349 (tsize and timeout) and RFC2090
 (multicast option). It also supports mtftp as defined in the PXE
@@ -151,7 +151,7 @@
 
 .TP
 .B \-\-pcre <file>
-Specify a pattern/replacement file to use. This allow to replace
+Specify a pattern/replacement file to use. This allows one to replace
 requested file name based on Perl Compatible Regular Expression. See
 README.PCRE.
 
@@ -169,7 +169,7 @@
 
 .TP
 .B \-\-mtftp\-port <port>
-Port the mtftp server shall listen to for incomming request.
+Port the mtftp server shall listen to for incoming request.
 
 .TP
 .B \-\-no\-source\-port\-checking
@@ -181,15 +181,23 @@
 option has effect only for non-multicast transfer.
 
 .TP
+.B \-\-prevent\-sas
+Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350.
+This RFC requires repeated responses to a single packet to be
+rejected. Thus a block will only get retransmitted on a timeout.
+For backward compatibility, the default stays to ignore this RFC.
+So blocks get transmitted on every request.
+
+.TP
 .B \-\-mcast\-switch\-client
-This option allow the server to proceed with the next multicast client
+This option allows the server to proceed with the next multicast client
 as soon as the current client timeout. When the current master client
 fails to send an acknowledge (ACK) to the server, the server will send
 an option acknowledge (OACK) to the master client with the field MC
 (master client) set to false and send an OACK to the next multicast
 client with MC set to true. Without this option, the server will retry
 the current master client up to 5 times and then mark it done,
-proceding with the next one.
+proceeding with the next one.
 
 .TP
 .B \-V, \-\-version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/compile new/atftp-0.7.5/compile
--- old/atftp-0.7.4/compile     2019-04-21 14:46:19.000000000 +0200
+++ new/atftp-0.7.5/compile     2021-06-05 00:16:24.000000000 +0200
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 # Written by Tom Tromey <tro...@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@
          MINGW*)
            file_conv=mingw
            ;;
-         CYGWIN*)
+         CYGWIN* | MSYS*)
            file_conv=cygwin
            ;;
          *)
@@ -67,7 +67,7 @@
        mingw/*)
          file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
          ;;
-       cygwin/*)
+       cygwin/* | msys/*)
          file=`cygpath -m "$file" || echo "$file"`
          ;;
        wine/*)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/configure.ac new/atftp-0.7.5/configure.ac
--- old/atftp-0.7.4/configure.ac        2021-02-02 00:52:24.000000000 +0100
+++ new/atftp-0.7.5/configure.ac        2021-09-14 00:23:03.000000000 +0200
@@ -10,7 +10,7 @@
 dnl Free Software Foundation; either version 2 of the License, or (at your
 dnl option) any later version.
 
-AC_INIT([atftp], [0.7.4])
+AC_INIT([atftp], [0.7.5])
 AC_CONFIG_SRCDIR([tftp.c])
 AM_INIT_AUTOMAKE
 
@@ -92,6 +92,11 @@
   fi
 fi
 
+case "$CC" in
+       gcc*|clang*) CFLAGS="$CFLAGS -std=gnu89"
+       ;;
+esac
+
 AC_PROG_MAKE_SET
 AC_PROG_INSTALL
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/logger.c new/atftp-0.7.5/logger.c
--- old/atftp-0.7.4/logger.c    2012-08-20 17:36:31.000000000 +0200
+++ new/atftp-0.7.5/logger.c    2021-09-13 00:14:14.000000000 +0200
@@ -87,7 +87,7 @@
 }
 
 /*
- * Same as syslog but allow to format a string, like printf, when logging to
+ * Same as syslog but allows one to format a string, like printf, when logging 
to
  * file. This fonction will either call syslog or fprintf depending of the
  * previous call to open_logger().
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/missing new/atftp-0.7.5/missing
--- old/atftp-0.7.4/missing     2019-04-21 14:46:19.000000000 +0200
+++ new/atftp-0.7.5/missing     2021-06-05 00:16:24.000000000 +0200
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pin...@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/options.c new/atftp-0.7.5/options.c
--- old/atftp-0.7.4/options.c   2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/options.c   2021-09-12 22:26:47.000000000 +0200
@@ -23,7 +23,7 @@
 #include <unistd.h>
 #include <syslog.h>
 
-#if HAVE_ARGZ
+#if HAVE_ARGZ_H
 #include <argz.h>
 #else
 #include "argz.h"
@@ -43,6 +43,12 @@
      struct tftphdr *tftp_data = (struct tftphdr *)data;
      size_t size = data_size - sizeof(tftp_data->th_opcode);
 
+     /* sanity check - requests always end in a null byte,
+      * check to prevent argz_next from reading past the end of
+      * data, as it doesn't do bounds checks */
+     if (data_size == 0 || data[data_size-1] != '\0')
+          return ERR;
+
      /* read filename */
      entry = argz_next(tftp_data->th_stuff, size, entry);
      if (!entry)
@@ -79,6 +85,12 @@
      struct tftphdr *tftp_data = (struct tftphdr *)data;
      size_t size = data_size - sizeof(tftp_data->th_opcode);
 
+     /* sanity check - options always end in a null byte,
+      * check to prevent argz_next from reading past the end of
+      * data, as it doesn't do bounds checks */
+     if (data_size == 0 || data[data_size-1] != '\0')
+          return ERR;
+
      while ((entry = argz_next(tftp_data->th_stuff, size, entry)))
      {
           tmp = entry;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/redhat/atftp.spec new/atftp-0.7.5/redhat/atftp.spec
--- old/atftp-0.7.4/redhat/atftp.spec   2021-02-02 01:05:22.000000000 +0100
+++ new/atftp-0.7.5/redhat/atftp.spec   2021-09-14 00:27:04.000000000 +0200
@@ -1,7 +1,7 @@
 Name: atftp
 Summary: Advanced Trivial File Transfer Protocol (ATFTP) - TFTP server
 Group: System Environment/Daemons
-Version: 0.7.4
+Version: 0.7.5
 Release: 1
 Copyright: GPL
 Vendor: Linux Networx Inc.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/stats.h new/atftp-0.7.5/stats.h
--- old/atftp-0.7.4/stats.h     2011-03-11 07:51:24.000000000 +0100
+++ new/atftp-0.7.5/stats.h     2021-09-13 00:14:14.000000000 +0200
@@ -44,7 +44,7 @@
      int number_of_err;         /* send or receive that return with error */
      int num_file_send;
      int num_file_recv;
-     int byte_send;             /* total byte transfered to client (file) */
+     int byte_send;             /* total byte transferred to client (file) */
      int byte_recv;             /* total byte read from client (file) */
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/test/Makefile new/atftp-0.7.5/test/Makefile
--- old/atftp-0.7.4/test/Makefile       2021-02-02 01:05:21.000000000 +0100
+++ new/atftp-0.7.5/test/Makefile       2021-09-14 00:27:04.000000000 +0200
@@ -324,16 +324,16 @@
        $(TEST_LOG_FLAGS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = ${SHELL} '/home/martin/swbuild/atftp/atftp.git/missing' aclocal-1.16
+ACLOCAL = ${SHELL} '/home/martin/swbuild/atftp/git/atftp.git/missing' 
aclocal-1.16
 AMTAR = $${TAR-tar}
 AM_DEFAULT_VERBOSITY = 1
-AUTOCONF = ${SHELL} '/home/martin/swbuild/atftp/atftp.git/missing' autoconf
-AUTOHEADER = ${SHELL} '/home/martin/swbuild/atftp/atftp.git/missing' autoheader
-AUTOMAKE = ${SHELL} '/home/martin/swbuild/atftp/atftp.git/missing' 
automake-1.16
+AUTOCONF = ${SHELL} '/home/martin/swbuild/atftp/git/atftp.git/missing' autoconf
+AUTOHEADER = ${SHELL} '/home/martin/swbuild/atftp/git/atftp.git/missing' 
autoheader
+AUTOMAKE = ${SHELL} '/home/martin/swbuild/atftp/git/atftp.git/missing' 
automake-1.16
 AWK = gawk
 CC = gcc
 CCDEPMODE = depmode=gcc3
-CFLAGS = -g -O2 -g -Wall -D_REENTRANT -O2
+CFLAGS = -g -O2 -g -Wall -D_REENTRANT -O2 -std=gnu89
 CPP = gcc -E
 CPPFLAGS = 
 CYGPATH_W = echo
@@ -350,7 +350,7 @@
 INSTALL_PROGRAM = ${INSTALL}
 INSTALL_SCRIPT = ${INSTALL}
 INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
-ISODATE = 2021-02-02
+ISODATE = 2021-09-14
 LDFLAGS = 
 LIBOBJS = 
 LIBPCRE = -lpcre
@@ -358,28 +358,28 @@
 LIBREADLINE = -lreadline
 LIBS = 
 LIBTERMCAP = 
-LIBWRAP = -lnsl -lwrap
+LIBWRAP = 
 LTLIBOBJS = 
-MAKEINFO = ${SHELL} '/home/martin/swbuild/atftp/atftp.git/missing' makeinfo
+MAKEINFO = ${SHELL} '/home/martin/swbuild/atftp/git/atftp.git/missing' makeinfo
 MKDIR_P = /bin/mkdir -p
 OBJEXT = o
 PACKAGE = atftp
 PACKAGE_BUGREPORT = 
 PACKAGE_NAME = atftp
-PACKAGE_STRING = atftp 0.7.4
+PACKAGE_STRING = atftp 0.7.5
 PACKAGE_TARNAME = atftp
 PACKAGE_URL = 
-PACKAGE_VERSION = 0.7.4
+PACKAGE_VERSION = 0.7.5
 PATH_SEPARATOR = :
 PLATFORM = pc-x86_64-linux-gnu
 SET_MAKE = 
 SHELL = /bin/sh
 STRIP = 
-VERSION = 0.7.4
-abs_builddir = /home/martin/swbuild/atftp/atftp.git/test
-abs_srcdir = /home/martin/swbuild/atftp/atftp.git/test
-abs_top_builddir = /home/martin/swbuild/atftp/atftp.git
-abs_top_srcdir = /home/martin/swbuild/atftp/atftp.git
+VERSION = 0.7.5
+abs_builddir = /home/martin/swbuild/atftp/git/atftp.git/test
+abs_srcdir = /home/martin/swbuild/atftp/git/atftp.git/test
+abs_top_builddir = /home/martin/swbuild/atftp/git/atftp.git
+abs_top_srcdir = /home/martin/swbuild/atftp/git/atftp.git
 ac_ct_CC = gcc
 am__include = include
 am__leading_dot = .
@@ -406,7 +406,7 @@
 htmldir = ${docdir}
 includedir = ${prefix}/include
 infodir = ${datarootdir}/info
-install_sh = ${SHELL} /home/martin/swbuild/atftp/atftp.git/install-sh
+install_sh = ${SHELL} /home/martin/swbuild/atftp/git/atftp.git/install-sh
 libdir = ${exec_prefix}/lib
 libexecdir = ${exec_prefix}/libexec
 localedir = ${datarootdir}/locale
@@ -442,9 +442,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign test/Makefile
+         $(AUTOMAKE) --gnu test/Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
          *config.status*) \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/test/test.sh new/atftp-0.7.5/test/test.sh
--- old/atftp-0.7.4/test/test.sh        2021-02-01 23:42:55.000000000 +0100
+++ new/atftp-0.7.5/test/test.sh        2021-09-12 13:12:30.000000000 +0200
@@ -45,12 +45,6 @@
 SERVER_ARGS="--daemon --no-fork --logfile=/dev/stdout --port=$PORT --verbose=6 
$DIRECTORY"
 SERVER_LOG=./atftpd.log
 
-# check if we are root or not root
-# if this test is executed by a normal user, atftpd will fail if we do not use 
our own user+group
-if [ ${UID} -ne 0 ]; then
-       SERVER_ARGS="--user=$(id -un) --group=$(id -gn) ${SERVER_ARGS}"
-fi
-
 ERROR=0
 
 # verify that atftp and atftpd are executable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/test-driver new/atftp-0.7.5/test-driver
--- old/atftp-0.7.4/test-driver 2019-04-21 14:46:19.000000000 +0200
+++ new/atftp-0.7.5/test-driver 2021-06-05 00:16:24.000000000 +0200
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -42,11 +42,13 @@
 {
   cat <<END
 Usage:
-  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
-              [--expect-failure={yes|no}] [--color-tests={yes|no}]
-              [--enable-hard-errors={yes|no}] [--]
+  test-driver --test-name NAME --log-file PATH --trs-file PATH
+              [--expect-failure {yes|no}] [--color-tests {yes|no}]
+              [--enable-hard-errors {yes|no}] [--]
               TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+
 The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+See the GNU Automake documentation for information.
 END
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/tftp.c new/atftp-0.7.5/tftp.c
--- old/atftp-0.7.4/tftp.c      2012-07-30 08:22:41.000000000 +0200
+++ new/atftp-0.7.5/tftp.c      2021-09-13 00:14:14.000000000 +0200
@@ -38,7 +38,7 @@
 #include <readline/history.h>
 #endif
 
-#if HAVE_ARGZ
+#if HAVE_ARGZ_H
 #include <argz.h>
 #else
 #include "argz.h"
@@ -58,6 +58,7 @@
 /* defined as extern in tftp_file.c and mtftp_file.c, set by the signal
    handler */
 int tftp_cancel = 0;
+int tftp_prevent_sas = 0;
 
 /* local flags */
 int interactive = 1;            /* if false, we run in batch mode */
@@ -708,11 +709,14 @@
                {
                     fclose(fp);
 #if HAVE_READLINE
-                    string = readline("Overwite local file [y/n]? ");
+                    string = readline("Overwrite local file [y/n]? ");
 #else
-                    fprintf(stderr, "Overwite local file [y/n]? ");
-                    fgets(string, MAXLEN, stdin);
-                    string[strlen(string) - 1] = 0;
+                    fprintf(stderr, "Overwrite local file [y/n]? ");
+                    if (fgets(string, MAXLEN, stdin) == NULL) {
+                         string[0] = 0;
+                    } else {
+                         string[strlen(string) - 1] = 0;
+                    }
 #endif
                     if (!(strcasecmp(string, "y") == 0))
                     {
@@ -908,7 +912,7 @@
           if (tftp_result == OK)
           {
                print_eng((double)data.file_size, string, sizeof(string), 
"%3.3f%cB");
-               fprintf(stderr, "  Bytes transfered:  %s\n", string);
+               fprintf(stderr, "  Bytes transferred:  %s\n", string);
                fprintf(stderr, "  Time of transfer: %8.3fs\n",
                        (double)(tmp.tv_sec + tmp.tv_usec * 1e-6));
                fprintf(stderr, "  Throughput:        ");
@@ -1006,6 +1010,7 @@
 #endif
           { "mtftp", 1, NULL, '1'},
           { "no-source-port-checking", 0, NULL, '0'},
+          { "prevent-sas", 0, NULL, 'X'},
           { "verbose", 0, NULL, 'v'},
           { "trace", 0, NULL, 'd'},
 #if DEBUG
@@ -1115,6 +1120,9 @@
           case '0':
                data.checkport = 0;
                break;
+          case 'X':
+               tftp_prevent_sas = 1;
+               break;
           case 'v':
                snprintf(string, sizeof(string), "verbose on");
                make_arg(string, &ac, &av);
@@ -1226,6 +1234,7 @@
              "  --mtftp <\"name value\">   : set mtftp variable to value\n"
 #endif
              "  --no-source-port-checking: violate RFC, see man page\n"
+             "  --prevent-sas            : prevent Sorcerer's Apprentice 
Syndrome\n"
              "  --verbose                : set verbose mode on\n"
              "  --trace                  : set trace mode on\n"
 #if DEBUG
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/tftp_file.c new/atftp-0.7.5/tftp_file.c
--- old/atftp-0.7.4/tftp_file.c 2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/tftp_file.c 2021-09-13 00:14:14.000000000 +0200
@@ -49,6 +49,7 @@
 #define NB_BLOCK        2048
 
 extern int tftp_cancel;
+extern int tftp_prevent_sas;
 
 /*
  * Find a hole in the file bitmap.
@@ -124,7 +125,7 @@
      struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer;
      FILE *fp = NULL;           /* the local file pointer */
      int number_of_timeout = 0;
-     int convert = 0;           /* if true, do netascii convertion */
+     int convert = 0;           /* if true, do netascii conversion */
 
      int oacks = 0;             /* count OACK for improved error checking */
      int multicast = 0;         /* set to 1 if multicast */
@@ -140,7 +141,7 @@
      int prev_bitmap_hole = -1; /* the previous hole found in the bitmap */
      char string[MAXLEN];
 
-     long prev_block_number = 0; /* needed to support netascii convertion */
+     long prev_block_number = 0; /* needed to support netascii conversion */
      int temp = 0;
      int err;
 
@@ -629,6 +630,7 @@
      int timeout_state = state; /* what state should we go on when timeout */
      int result;
      long block_number = 0;
+     long last_requested_block = -1;
      long last_block = -1;
      int data_size;             /* size of data received */
      int sockfd = data->sockfd; /* just to simplify calls */
@@ -640,10 +642,10 @@
      FILE *fp;                  /* the local file pointer */
      int number_of_timeout = 0;
      struct stat file_stat;
-     int convert = 0;           /* if true, do netascii convertion */
+     int convert = 0;           /* if true, do netascii conversion */
      char string[MAXLEN];
 
-     long prev_block_number = 0; /* needed to support netascii convertion */
+     long prev_block_number = 0; /* needed to support netascii conversion */
      long prev_file_pos = 0;
      int temp = 0;
 
@@ -791,6 +793,18 @@
                     }
                    block_number = tftp_rollover_blocknumber(
                        ntohs(tftphdr->th_block), prev_block_number, 0);
+
+                    /* if turned on, check whether the block request isn't 
already fulfilled */
+                    if (tftp_prevent_sas) {
+                         if (last_requested_block >= block_number) {
+                              if (data->trace)
+                                   fprintf(stderr, "received duplicated ACK 
<block: %ld >= %ld>\n",
+                                           last_requested_block, block_number);
+                              break;
+                         } else
+                              last_requested_block = block_number;
+                    }
+
                     if (data->trace)
                          fprintf(stderr, "received ACK <block: %ld>\n",
                                  block_number);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/tftp_io.c new/atftp-0.7.5/tftp_io.c
--- old/atftp-0.7.4/tftp_io.c   2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/tftp_io.c   2021-09-13 00:14:14.000000000 +0200
@@ -64,7 +64,7 @@
      buf_index += strlen(mode);
      buf_index++;
      
-     for (i = 2; ; i++)
+     for (i = 2; i < OPT_NUMBER; i++)
      {
           if (strlen(tftp_options[i].option) == 0)
                break;
@@ -391,11 +391,8 @@
           */
          if ((block_number != *prev_block_number) && (block_number != 
*prev_block_number + 1))
               return ERR;
-         if (block_number == *prev_block_number)
-         {
-              if (fseek(fp, *prev_file_pos, SEEK_SET) != 0)
-                    return ERR;
-         }
+         if (block_number == *prev_block_number && fseek(fp, *prev_file_pos, 
SEEK_SET) != 0)
+          return ERR;
 
          *prev_file_pos = ftell(fp);
 
@@ -445,7 +442,7 @@
                     int convert, long *prev_block_number, int *temp)
 {
      static long filepos;
-     int bytes_written;
+     int bytes_written = 0;
      int c;
      char prevchar = *temp;
 
@@ -454,11 +451,13 @@
          /* Simple case, just seek and write */
           long position = (block_number - 1)*data_buffer_size;
           if (position != filepos)
+          {
                if (fseek(fp, position, SEEK_SET) != 0)
                     return 0;
                else
                     filepos = position;
-         bytes_written = fwrite(data_buffer, 1, data_size, fp);
+          }
+          bytes_written = fwrite(data_buffer, 1, data_size, fp);
           filepos += bytes_written;
      }
      else if (block_number != *prev_block_number)
@@ -482,20 +481,21 @@
                {
                     if (c == '\n')
                     {
-                         fseek(fp, -1, SEEK_CUR); /* cr,lf to lf */
+                         if (fseek(fp, -1, SEEK_CUR) != 0) /* cr,lf to lf */
+                              return ERR;
                          if (fputc(c, fp) == EOF)
-                              break;
+                              return ERR;
                     }
                     else if (c != '\0')           /* cr,nul to cr */
                     {
                          if (fputc(c, fp) == EOF)
-                              break;
+                              return ERR;
                     }
                }
                else
                {
                     if (fputc(c, fp) == EOF)
-                         break;
+                         return ERR;
                }
                prevchar = c;
           }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/tftp_mtftp.c new/atftp-0.7.5/tftp_mtftp.c
--- old/atftp-0.7.4/tftp_mtftp.c        2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/tftp_mtftp.c        2021-09-13 00:14:14.000000000 +0200
@@ -148,7 +148,7 @@
 
      /* check to see if conversion is requiered */
      if (strcasecmp(data->tftp_options[OPT_MODE].value, "netascii") == 0)
-          fprintf(stderr, "netascii convertion ignored\n");
+          fprintf(stderr, "netascii conversion ignored\n");
 
      /* make sure the data buffer is SEGSIZE + 4 bytes */
      if (data->data_buffer_size != (SEGSIZE + 4))
@@ -445,10 +445,14 @@
           case S_DATA_RECEIVED:
                block_number = ntohs(tftphdr->th_block);
                if (data->trace)
-                    fprintf(stderr, "received DATA <block: %ld, size: %d>\n",
-                            block_number, data_size - 4);
-               fseek(fp, (block_number - 1) * (data->data_buffer_size - 4),
-                     SEEK_SET);
+                    fprintf(stderr, "received DATA <block: %d, size: %d>\n",
+                            ntohs(tftphdr->th_block), data_size - 4);
+               if (fseek(fp, (block_number - 1) * (data->data_buffer_size - 4),
+                     SEEK_SET) != 0)
+               {
+                    state = S_ABORT;
+                    break;
+               }
                if ((int)fwrite(tftphdr->th_data, 1, data_size - 4, fp) !=
                    (data_size - 4))
                {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/tftpd.c new/atftp-0.7.5/tftpd.c
--- old/atftp-0.7.4/tftpd.c     2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/tftpd.c     2021-09-13 00:14:14.000000000 +0200
@@ -65,6 +65,8 @@
 
 int tftpd_daemon = 0;           /* By default we are started by inetd */
 int tftpd_daemon_no_fork = 0;   /* For who want a false daemon mode */
+int tftpd_prevent_sas = 0;      /* For who don't want the sorcerer's 
apprentice syndrome */
+int drop_privs = 0;             /* whether it was explicitly requested to 
switch to another user. */
 short tftpd_port = 69;          /* Port atftpd listen to */
 char tftpd_addr[MAXLEN] = "";   /* IP address atftpd binds to */
 
@@ -186,12 +188,12 @@
      }
 
      /*
-      * Can't be started from the prompt without explicitely specifying
+      * Can't be started from the prompt without explicitly specifying
       * the --daemon option.
       */
      if (isatty(0) && !(tftpd_daemon))
      {
-         printf("Can't be started from the prompt without explicitely "
+         printf("Can't be started from the prompt without explicitly "
                 "specifying the --daemon option.\n");
           tftpd_usage();
           exit(1);
@@ -297,14 +299,35 @@
           close(sockfd);
 
           /* release priviliedge */
-          user = getpwnam(user_name);
-          group = getgrnam(group_name);
-          if (!user || !group)
-          {
-               logger(LOG_ERR,
-                      "atftpd: can't change identity to %s.%s, exiting.",
-                      user_name, group_name);
-               exit(1);
+
+          /* first see if we are or can somehow become root, if so prepare
+           * for drop even if not requested on command line */
+          if (geteuid() == 0)
+          {
+               drop_privs = 1;
+          }
+          else if (getuid() == 0)
+          {
+               if (seteuid(0) == 0)
+                    drop_privs = 1;
+          }
+
+          if (drop_privs)
+          {
+               user = getpwnam(user_name);
+               group = getgrnam(group_name);
+               if (!user || !group)
+               {
+                    logger(LOG_ERR,
+                           "atftpd: can't change identity to %s.%s: no such 
user/group. exiting.",
+                           user_name, group_name);
+                    exit(1);
+               }
+          }
+          else
+          { /* make null pointers to prevent goofing up in case we accidenally 
access them */
+               user = NULL;
+               group = NULL;
           }
 
           /* write our pid in the specified file before changing user*/
@@ -318,26 +341,27 @@
                     exit(1);
                }
                /* to be able to remove it later */
-               if (chown(pidfile, user->pw_uid, group->gr_gid) != OK) {
-                   logger(LOG_ERR,
-                          "atftpd: failed to chown our pid file %s to owner 
%s.%s.",
+               if (drop_privs && chown(pidfile, user->pw_uid, group->gr_gid) 
!= OK) {
+                 logger(LOG_ERR,
+                     "atftpd: failed to chown our pid file %s to owner %s.%s.",
                            pidfile, user_name, group_name);
                     exit(1);
-              }
+               }
           }
 
-         if (setgid(group->gr_gid) != OK) {
-             logger(LOG_ERR,
-                     "atftpd: failed to setgid to group %d (%s).",
-                     group->gr_gid, group_name);
-             exit(1);
-         }
-         if (setuid(user->pw_uid) != OK) {
-             logger(LOG_ERR,
-                     "atftpd: failed to setuid to user %d (%s).",
-                     user->pw_uid, user_name);
-             exit(1);
-         }
+          if (drop_privs)
+          {
+               if (setregid(group->gr_gid, group->gr_gid) == -1)
+               {
+                    logger(LOG_ERR, "atftpd: failed to setregid to %s.", 
group_name);
+                    exit(1);
+               }
+               if (setreuid(user->pw_uid, user->pw_uid) == -1)
+               {
+                    logger(LOG_ERR, "atftpd: failed to setreuid to %s.", 
user_name);
+                    exit(1);
+               }
+          }
 
           /* Reopen log file now that we changed user, and that we've
            * open and dup2 the socket. */
@@ -345,7 +369,7 @@
      }
 
 #if defined(SOL_IP) && defined(IP_PKTINFO)
-     /* We need to retieve some information from incomming packets */
+     /* We need to retieve some information from incoming packets */
      if (setsockopt(0, SOL_IP, IP_PKTINFO, &one, sizeof(one)) != 0)
      {
           logger(LOG_WARNING, "Failed to set socket option: %s", 
strerror(errno));
@@ -429,7 +453,7 @@
           }
 #endif
 
-          /* A timeout of 0 is interpreted as infinity. Wait for incomming
+          /* A timeout of 0 is interpreted as infinity. Wait for incoming
              packets */
           if (!tftpd_cancel)
           {
@@ -524,6 +548,9 @@
                                   (void *)new) != 0)
                {
                     logger(LOG_ERR, "Failed to start new thread");
+                    free(new->data_buffer);
+                    free(new->tftp_options);
+                    free(new->client_info);
                     free(new);
                     pthread_mutex_unlock(&stdin_mutex);
                }
@@ -927,6 +954,7 @@
           { "mtftp", 1, NULL, OPT_MTFTP },
           { "mtftp-port", 1, NULL, OPT_MTFTP_PORT },
 #endif
+          { "prevent-sas", 0, NULL, 'X' },
           { "no-source-port-checking", 0, NULL, OPT_PORT_CHECK },
           { "mcast-switch-client", 0, NULL, OPT_MCAST_SWITCH },
           { "version", 0, NULL, 'V' },
@@ -996,6 +1024,9 @@
           case 'N':
                tftpd_daemon_no_fork = 1;
                break;
+          case 'X':
+               tftpd_prevent_sas = 1;
+               break;
           case 'U':
                tmp = strtok(optarg, ".");
                if (tmp != NULL)
@@ -1003,9 +1034,11 @@
                tmp = strtok(NULL, "");
                if (tmp != NULL)
                     Strncpy(group_name, tmp, MAXLEN);
+               drop_privs = 1;
                break;
           case 'G':
                Strncpy(group_name, optarg, MAXLEN);
+               drop_privs = 1;
                break;
           case 'P':
                tftpd_port = (short)atoi(optarg);
@@ -1228,6 +1261,7 @@
             "  --listen-local             : force listen on local network 
address\n"
             "  --daemon                   : run atftpd standalone (no inetd)\n"
             "  --no-fork                  : run as a daemon, don't fork\n"
+            "  --prevent-sas              : prevent Sorcerer's Apprentice 
Syndrome\n"
             "  --user <user[.group]>      : default is nobody\n"
             "  --group <group>            : default is nogroup\n"
             "  --port <port>              : port on which atftp listen\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/tftpd_file.c new/atftp-0.7.5/tftpd_file.c
--- old/atftp-0.7.4/tftpd_file.c        2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/tftpd_file.c        2021-09-13 00:14:14.000000000 +0200
@@ -55,6 +55,7 @@
 extern char directory[MAXLEN];
 /* read only except for the main thread */
 extern int tftpd_cancel;
+extern int tftpd_prevent_sas;
 
 #ifdef HAVE_PCRE
 extern tftpd_pcre_self_t *pcre_top;
@@ -114,22 +115,22 @@
      struct sockaddr_storage from;
      char addr_str[SOCKADDR_PRINT_ADDR_LEN];
      struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer;
-     FILE *fp;
+     FILE *fp = NULL;
      char filename[MAXLEN];
      char string[MAXLEN];
      int timeout = data->timeout;
      int number_of_timeout = 0;
      int all_blocks_received = 0; /* temporary kludge */
-     int convert = 0;           /* if true, do netascii convertion */
+     int convert = 0;           /* if true, do netascii conversion */
 
-     long prev_block_number = 0; /* needed to support netascii convertion */
+     long prev_block_number = 0; /* needed to support netascii conversion */
      int temp = 0;
 
      /* look for mode option */
      if (strcasecmp(data->tftp_options[OPT_MODE].value, "netascii") == 0)
      {
           convert = 1;
-          logger(LOG_DEBUG, "will do netascii convertion");
+          logger(LOG_DEBUG, "will do netascii conversion");
      }
 
      /* file name verification */
@@ -144,18 +145,6 @@
           return ERR;
      }
 
-     /* Open the file for writing. */
-     if ((fp = fopen(filename, "w")) == NULL)
-     {
-          /* Can't create the file. */
-          logger(LOG_INFO, "Can't open %s for writing", filename);
-          tftp_send_error(sockfd, sa, EACCESS, data->data_buffer, 
data->data_buffer_size);
-          if (data->trace)
-               logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", EACCESS,
-                      tftp_errmsg[EACCESS]);
-          return ERR;
-     }
-
      /* tsize option */
      if (((result = opt_get_tsize(data->tftp_options)) > -1) && !convert)
      {
@@ -172,7 +161,6 @@
                if (data->trace)
                     logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", 
EOPTNEG,
                            tftp_errmsg[EOPTNEG]);
-               fclose(fp);
                return ERR;
           }
           timeout = result;
@@ -180,16 +168,28 @@
           logger(LOG_DEBUG, "timeout option -> %d", timeout);
      }
 
-     /* blksize options */
+     /*
+      *  blksize option, must be the last option evaluated,
+      *  because data->data_buffer_size may be modified here,
+      *  and may be smaller than the buffer containing options
+      */
      if ((result = opt_get_blksize(data->tftp_options)) > -1)
      {
-          if ((result < 8) || (result > 65464))
+          /*
+           *  If we receive more options, we have to make sure our buffer for
+           *  the OACK is not too small.  Use the string representation of
+           *  the options here for simplicity, which puts us on the save side.
+           *  FIXME: Use independent buffers for OACK and data.
+           */
+          opt_options_to_string(data->tftp_options, string, MAXLEN);
+          if ((result < strlen(string)-2) || (result > 65464))
           {
+               logger(LOG_NOTICE, "options <%s> require roughly a blksize of 
%d for the OACK.",
+                      string, strlen(string)-2);
                tftp_send_error(sockfd, sa, EOPTNEG, data->data_buffer, 
data->data_buffer_size);
                if (data->trace)
                     logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", 
EOPTNEG,
                            tftp_errmsg[EOPTNEG]);
-               fclose(fp);
                return ERR;
           }
 
@@ -199,7 +199,6 @@
           if (data->data_buffer == NULL)
           {
                logger(LOG_ERR, "memory allocation failure");
-               fclose(fp);
                return ERR;
           }
           tftphdr = (struct tftphdr *)data->data_buffer;
@@ -210,7 +209,6 @@
                if (data->trace)
                     logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", 
ENOSPACE,
                            tftp_errmsg[ENOSPACE]);
-               fclose(fp);
                return ERR;
           }
           opt_set_blksize(result, data->tftp_options);
@@ -345,6 +343,20 @@
                }
                break;
           case S_DATA_RECEIVED:
+               if (fp == NULL) {
+                       /* Open the file for writing. */
+                       if ((fp = fopen(filename, "w")) == NULL)
+                       {
+                               /* Can't create the file. */
+                               logger(LOG_INFO, "Can't open %s for writing", 
filename);
+                               tftp_send_error(sockfd, sa, EACCESS, 
data->data_buffer, data->data_buffer_size);
+                               if (data->trace)
+                                       logger(LOG_DEBUG, "sent ERROR <code: 
%d, msg: %s>", EACCESS,
+                                                       tftp_errmsg[EACCESS]);
+                               return ERR;
+                       }
+               }
+
                /* We need to seek to the right place in the file */
               block_number = tftp_rollover_blocknumber(
                      ntohs(tftphdr->th_block), prev_block_number, 0);
@@ -373,13 +385,13 @@
                state = S_SEND_ACK;
                break;
           case S_END:
-               fclose(fp);
+               if (fp != NULL) fclose(fp);
                return OK;
           case S_ABORT:
-               fclose(fp);
+               if (fp != NULL) fclose(fp);
                return ERR;
           default:
-               fclose(fp);
+               if (fp != NULL) fclose(fp);
                logger(LOG_ERR, "%s: %d: tftpd_file.c: huh?",
                       __FILE__, __LINE__);
                return ERR;
@@ -430,15 +442,20 @@
      struct client_info *client_old = NULL;
      struct tftp_opt options[OPT_NUMBER];
 
-     long prev_block_number = 0; /* needed to support netascii convertion */
+     long prev_block_number = 0; /* needed to support netascii conversion */
      long prev_file_pos = 0;
      int temp = 0;
 
+     long prev_sent_block = -1;
+     int prev_sent_count = 0;
+     int prev_ack_count = 0;
+     int curr_sent_count = 0;
+
      /* look for mode option */
      if (strcasecmp(data->tftp_options[OPT_MODE].value, "netascii") == 0)
      {
           convert = 1;
-          logger(LOG_DEBUG, "will do netascii convertion");
+          logger(LOG_DEBUG, "will do netascii conversion");
      }
 
      /* file name verification */
@@ -527,11 +544,24 @@
           logger(LOG_INFO, "timeout option -> %d", timeout);
      }
 
-     /* blksize options */
+     /*
+      *  blksize option, must be the last option evaluated,
+      *  because data->data_buffer_size may be modified here,
+      *  and may be smaller than the buffer containing options
+      */
      if ((result = opt_get_blksize(data->tftp_options)) > -1)
      {
-          if ((result < 8) || (result > 65464))
+          /*
+           *  If we receive more options, we have to make sure our buffer for
+           *  the OACK is not too small.  Use the string representation of
+           *  the options here for simplicity, which puts us on the save side.
+           *  FIXME: Use independent buffers for OACK and data.
+           */
+          opt_options_to_string(data->tftp_options, string, MAXLEN);
+          if ((result < strlen(string)-2) || (result > 65464))
           {
+               logger(LOG_NOTICE, "options <%s> require roughly a blksize of 
%d for the OACK.",
+                      string, strlen(string)-2);
                tftp_send_error(sockfd, sa, EOPTNEG, data->data_buffer, 
data->data_buffer_size);
                if (data->trace)
                     logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", 
EOPTNEG,
@@ -631,7 +661,7 @@
                               data->data_buffer, data->data_buffer_size);
 
                /* We are done */
-               logger(LOG_INFO, "Client transfered to %p", thread);
+               logger(LOG_INFO, "Client transferred to %p", thread);
                fclose(fp);
                return OK;
           }
@@ -818,6 +848,10 @@
                                           sockaddr_get_port(
                                                &client_info->client));
                                    sa = &client_info->client;
+
+                                   /* rewind the prev_sent_block counter */
+                                   prev_sent_block = -1;
+
                                    state = S_SEND_OACK;
                                    break;
                               }
@@ -891,6 +925,7 @@
                                           "source port mismatch, check 
bypassed");
                          }
                     }
+
                     /* The ACK is from the current client */
                     number_of_timeout = 0;
                    if (multicast)
@@ -903,11 +938,93 @@
                     if (data->trace)
                          logger(LOG_DEBUG, "received ACK <block: %ld>",
                                 block_number);
+
+                    /* Now check the ACK number and possibly ignore the 
request */
+
+                    /* multicast, block numbers could contain gaps */
+                    if (multicast) {
+                         /* if turned on, check whether the block request 
isn't already fulfilled */
+                         if (tftpd_prevent_sas) {
+                              if (prev_sent_block >= block_number) {
+                                   if (data->trace)
+                                        logger(LOG_DEBUG, "received duplicated 
ACK <block: %d >= %d>", prev_sent_block, block_number);
+                                   break;
+                              } else
+                                   prev_sent_block = block_number;
+                         }
+                         /* don't prevent thes SAS */
+                         /* use a heuristic suggested by Vladimir Nadvornik */
+                         else {
+                              /* here comes the ACK again */
+                              if (prev_sent_block == block_number) {
+                                   /* drop if number of ACKs == times of 
previous block sending */
+                                   if (++prev_ack_count == prev_sent_count) {
+                                        logger(LOG_DEBUG, "ACK count (%d) == 
previous block transmission count -> dropping ACK", prev_ack_count);
+                                        break;
+                                   }
+                                   /* else resend the block */
+                                   logger(LOG_DEBUG, "resending block %d", 
block_number + 1);
+                              }
+                              /* received ACK to sent block -> move on to next 
block */
+                              else if (prev_sent_block < block_number) {
+                                   prev_sent_block = block_number;
+                                   prev_sent_count = curr_sent_count;
+                                   curr_sent_count = 0;
+                                   prev_ack_count = 1;
+                              }
+                              /* block with low number -> ignore it completely 
*/
+                              else {
+                                   logger(LOG_DEBUG, "ignoring ACK %d", 
block_number);
+                                   break;
+                              }
+                         }
+                         /* unicast, blocks should be requested one after 
another */
+                    } else {
+                         /* if turned on, check whether the block request 
isn't already fulfilled */
+                         if (tftpd_prevent_sas) {
+                              if (prev_sent_block + 1 != block_number) {
+                                   logger(LOG_WARNING, "timeout: retrying...");
+                                   if (data->trace)
+                                        logger(LOG_DEBUG, "received out of 
order ACK <block: %d != %d>", prev_sent_block + 1, block_number);
+                                   break;
+                              } else {
+                                   prev_sent_block = block_number;
+                              }
+                              /* don't prevent thes SAS */
+                              /* use a heuristic suggested by Vladimir 
Nadvornik */
+                              } else {
+                              /* here comes the ACK again */
+                              if (prev_sent_block == block_number) {
+                                   /* drop if number of ACKs == times of 
previous block sending */
+                                   if (++prev_ack_count == prev_sent_count) {
+                                        logger(LOG_DEBUG, "ACK count (%d) == 
previous block transmission count -> dropping ACK", prev_ack_count);
+                                        break;
+                                   }
+                                   /* else resend the block */
+                                   logger(LOG_DEBUG, "resending block %d", 
block_number + 1);
+                              }
+                              /* received ACK to sent block -> move on to next 
block */
+                              else if (prev_sent_block < block_number) {
+                                   prev_sent_block = block_number;
+                                   prev_sent_count = curr_sent_count;
+                                   curr_sent_count = 0;
+                                   prev_ack_count = 1;
+                              }
+                              /* nor previous nor current block number -> 
ignore it completely */
+                              else {
+                                   logger(LOG_DEBUG, "ignoring ACK %d", 
block_number);
+                                   break;
+                              }
+                         }
+                    }
+
                     if ((last_block != -1) && (block_number > last_block))
                     {
                          state = S_END;
                          break;
                     }
+
+                    curr_sent_count++;
                     state = S_SEND_DATA;
                     break;
                case GET_ERROR:
@@ -1001,10 +1118,12 @@
                          /* nedd to send an oack to that client */
                          state = S_SEND_OACK;                
                          fseek(fp, 0, SEEK_SET);
+                        /* reset the last block received counter */
+                        prev_sent_block = -1;
                     }
                     else
                     {
-                         logger(LOG_INFO, "No more client, end of tranfers");
+                         logger(LOG_INFO, "No more client, end of transfers");
                          fclose(fp);
                          return OK;
                     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/atftp-0.7.4/tftpd_mtftp.c new/atftp-0.7.5/tftpd_mtftp.c
--- old/atftp-0.7.4/tftpd_mtftp.c       2021-01-31 23:59:14.000000000 +0100
+++ new/atftp-0.7.5/tftpd_mtftp.c       2021-09-12 13:12:30.000000000 +0200
@@ -550,8 +550,12 @@
                /* The first data packet as to be sent to the unicast address
                   of the client */
                timeout_state = state;
-               fseek(data->fp, block_number * (data->data_buffer_size - 4),
-                     SEEK_SET);
+               if (fseek(data->fp, block_number * (data->data_buffer_size - 4),
+                     SEEK_SET) != 0)
+               {
+                    state = S_ABORT;
+                    break;
+               }
                /* read data from file */
                data_size = fread(tftphdr->th_data, 1,
                                  data->data_buffer_size - 4, data->fp) + 4;
@@ -568,8 +572,12 @@
                break;
           case S_SEND_DATA:
                timeout_state = state;
-               fseek(data->fp, block_number * (data->data_buffer_size - 4),
-                     SEEK_SET);
+               if (fseek(data->fp, block_number * (data->data_buffer_size - 4),
+                     SEEK_SET) != 0)
+               {
+                    state = S_ABORT;
+                    break;
+               }
                /* read data from file */
                data_size = fread(tftphdr->th_data, 1,
                                  data->data_buffer_size - 4, data->fp) + 4;

++++++ atftp-drop_privileges_non-daemon.patch ++++++
--- /var/tmp/diff_new_pack.TBgH6m/_old  2021-09-25 00:35:36.063142324 +0200
+++ /var/tmp/diff_new_pack.TBgH6m/_new  2021-09-25 00:35:36.063142324 +0200
@@ -1,8 +1,8 @@
-Index: atftp-0.7.2/tftpd.c
+Index: atftp-0.7.5/tftpd.c
 ===================================================================
---- atftp-0.7.2.orig/tftpd.c
-+++ atftp-0.7.2/tftpd.c
-@@ -98,8 +98,8 @@ int deny_severity = LOG_NOTICE;
+--- atftp-0.7.5.orig/tftpd.c
++++ atftp-0.7.5/tftpd.c
+@@ -99,8 +99,8 @@ int deny_severity = LOG_NOTICE;
  #endif
  
  /* user ID and group ID when running as a daemon */
@@ -13,94 +13,12 @@
  
  /* For special uses, disable source port checking */
  int source_port_checking = 1;
-@@ -296,54 +296,46 @@ int main(int argc, char **argv)
-            */
+@@ -298,7 +298,7 @@ int main(int argc, char **argv)
            dup2(sockfd, 0);
            close(sockfd);
-+     }
  
 -          /* release priviliedge */
--          user = getpwnam(user_name);
--          group = getgrnam(group_name);
--          if (!user || !group)
--          {
--               logger(LOG_ERR,
--                      "atftpd: can't change identity to %s.%s, exiting.",
--                      user_name, group_name);
--               exit(1);
--          }
-+     /* release privilege */
-+     user = getpwnam(user_name);
-+     group = getgrnam(group_name);
-+     if (!user || !group)
-+     {
-+          logger(LOG_ERR,
-+                 "atftpd: can't change identity to %s.%s, exiting.",
-+                 user_name, group_name);
-+          exit(1);
-+     }
++          /* release priviledge */
  
--          /* write our pid in the specified file before changing user*/
--          if (pidfile)
--          {
--               if (tftpd_pid_file(pidfile, 1) != OK)
--               {
--                    logger(LOG_ERR,
--                           "atftpd: can't write our pid file: %s.",
--                           pidfile);
--                    exit(1);
--               }
--               /* to be able to remove it later */
--               if (chown(pidfile, user->pw_uid, group->gr_gid) != OK) {
--                  logger(LOG_ERR,
--                         "atftpd: failed to chown our pid file %s to owner 
%s.%s.",
--                           pidfile, user_name, group_name);
--                    exit(1);
--             }
--          }
-+     /* write our pid in the specified file before changing user */
-+     if (pidfile)
-+     {
-+          if (tftpd_pid_file(pidfile, 1) != OK)
-+               exit(1);
-+          /* to be able to remove it later */
-+          chown(pidfile, user->pw_uid, group->gr_gid);
-+     }
- 
--        if (setgid(group->gr_gid) != OK) {
--            logger(LOG_ERR,
--                    "atftpd: failed to setgid to group %d (%s).",
--                    group->gr_gid, group_name);
--            exit(1);
--        }
--        if (setuid(user->pw_uid) != OK) {
--            logger(LOG_ERR,
--                    "atftpd: failed to setuid to user %d (%s).",
--                    user->pw_uid, user_name);
--            exit(1);
--        }
--
--          /* Reopen log file now that we changed user, and that we've
--           * open and dup2 the socket. */
--          open_logger("atftpd", log_file, logging_level);
-+     if (setgid(group->gr_gid) != OK) {
-+          logger(LOG_ERR,
-+                 "atftpd: failed to setgid to group %d (%s).",
-+                 group->gr_gid, group_name);
-+          exit(1);
-      }
-+     if (setgroups(0, NULL)) {
-+          logger(LOG_ERR, "atftpd: can't clear supplementary group list");
-+          exit(1);
-+     }
-+     if(setuid(user->pw_uid)) {
-+          logger(LOG_ERR, "atftpd: can't switch user to %s, exiting.", 
user_name);
-+          exit(1);
-+     }
-+
-+     /* Reopen log file now that we changed user, and that we've
-+      * open and dup2 the socket. */
-+     open_logger("atftpd", log_file, logging_level);
- 
- #if defined(SOL_IP) && defined(IP_PKTINFO)
-      /* We need to retieve some information from incomming packets */
+           /* first see if we are or can somehow become root, if so prepare
+            * for drop even if not requested on command line */

++++++ atftpd.service ++++++
--- /var/tmp/diff_new_pack.TBgH6m/_old  2021-09-25 00:35:36.091142353 +0200
+++ /var/tmp/diff_new_pack.TBgH6m/_new  2021-09-25 00:35:36.091142353 +0200
@@ -2,6 +2,19 @@
 Description=Advanced TFTP Server
 
 [Service]
+# added automatically, for details please see
+# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
+ProtectSystem=full
+ProtectHome=true
+PrivateDevices=true
+ProtectHostname=true
+ProtectClock=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+RestrictRealtime=true
+# end of automatic additions 
 EnvironmentFile=/etc/sysconfig/atftpd
 # atftpd does not create logfile when there is none
 ExecStartPre=-/usr/bin/su -c "/usr/bin/touch $ATFTPD_LOGFILE" -s /bin/bash 
$ATFTPD_USER

Reply via email to