SHA256
1
0
forked from pool/atftp
atftp/atftp-0.7-ack_heuristic.patch
Pedro Monreal Gonzalez 222c2ec04b Accepting request 698118 from home:pmonrealgonzalez:branches:network
- Removed old initscript conditionals and atftpd.init file

- Update to version 0.7.2 [bsc#1133114, CVE-2019-11365][bsc#1133145, CVE-2019-11366]
  * atftpd.c: Fixed a potential DoS bug (introduced by the IPv6 patch)
  * Fix Debian Bug deb#613582 and deb#258998 atftpd: does not reply properly when there's more than 1 interface
  * Fix Debian Bug deb#622840 atftpd: Forgets port if both --port and --bind-address are used
  * Fix Debian Bug deb#606969 atftp exits with no error after a get when disk is full
  * Fix Debian Bug deb#575831 atftp: error return value when tftp put file
  * Fix missing default port from Ubuntu bug lp#972834 
  * Merged patches to improve debugging and warning messages
  * Merged patch from Gentoo distribution: 
    add support for proprietary password extension necessary for
    transferring files to linksys routers (atftp client)
  * Added patch from Gentoo bug #322601: client fails for filenames containing spaces
  * Listening Address configuration fixed
  * Added Patch "Blksize option can be smaller than SEGSIZE" 
  * Fix Debian Bug deb#609813 Apply patch listen on requested port when in daemon mode.
  * Fix Debian Bug deb#598474 Fixed use of sendto() over a connected datagram socket on FreeBSD
  * Fix Debian Bug deb#580473 Apply IPv6 support patch by Ben Hutchings.
    Add AC_GNU_SOURCE to configure.ac to address FTBFS.
  * Fix Debian Bug deb#536295 Updated config.sub .guess.
  * Fix Debian Bug deb#535604 Make sure we have the --daemon option before starting atftpd
  * Fix Debian Bug deb#514521 Crash fix
  * Fix Debian Bug deb#484739 Added support for logging to stdout.
  * Fix Debian Bug deb#484932 inetd.conf: change udp to udp4
  * Fix Debian Bug deb#436310 Fixed the FTBFS.
  * Fix Debian Bug deb#420900 Use CLOCKS_PER_SEC instead of CLK_TCK. Fixed a FTBFS.
  * Fix Debian Bug deb#271816 Random segfaults fixed
  * Fix Debian Bug deb#291829 Segfault fixed on AMD64.
  * Fix Debian Bug deb#290062 Copyright fixed.

OBS-URL: https://build.opensuse.org/request/show/698118
OBS-URL: https://build.opensuse.org/package/show/network/atftp?expand=0&rev=38
2019-04-26 09:54:01 +00:00

158 lines
8.3 KiB
Diff

Index: tftpd_file.c
===================================================================
--- tftpd_file.c.orig
+++ tftpd_file.c
@@ -406,7 +406,6 @@ int tftpd_send_file(struct thread_data *
int timeout_state = state;
int result;
long block_number = 0;
- long last_requested_block = -1;
long last_block = -1;
int data_size;
struct sockaddr_storage *sa = &data->client_info->client;
@@ -434,6 +433,11 @@ int tftpd_send_file(struct thread_data *
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)
{
@@ -819,8 +823,8 @@ int tftpd_send_file(struct thread_data *
&client_info->client));
sa = &client_info->client;
- /* rewind the last_requested_block counter */
- last_requested_block = -1;
+ /* rewind the prev_sent_block counter */
+ prev_sent_block = -1;
state = S_SEND_OACK;
break;
@@ -895,6 +899,7 @@ int tftpd_send_file(struct thread_data *
"source port mismatch, check bypassed");
}
}
+
/* The ACK is from the current client */
number_of_timeout = 0;
if (multicast)
@@ -908,24 +913,82 @@ int tftpd_send_file(struct thread_data *
logger(LOG_DEBUG, "received ACK <block: %ld>",
block_number);
- /* if turned on, check whether the block request isn't already fulfilled */
- if (tftpd_prevent_sas) {
- /* multicast, block numbers could contain gaps */
- if (multicast) {
- if (last_requested_block >= 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>", last_requested_block, block_number);
+ logger(LOG_DEBUG, "received duplicated ACK <block: %d >= %d>", prev_sent_block, block_number);
break;
} else
- last_requested_block = block_number;
- /* unicast, blocks should be requested one after another */
- } else {
- if (last_requested_block + 1 != block_number && last_requested_block != -1) {
+ 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>", last_requested_block + 1, block_number);
+ logger(LOG_DEBUG, "received out of order ACK <block: %d != %d>", prev_sent_block + 1, block_number);
break;
- } else
- last_requested_block = block_number;
+ } 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;
+ }
}
}
@@ -934,6 +997,8 @@ int tftpd_send_file(struct thread_data *
state = S_END;
break;
}
+
+ curr_sent_count++;
state = S_SEND_DATA;
break;
case GET_ERROR:
@@ -1028,7 +1093,7 @@ int tftpd_send_file(struct thread_data *
state = S_SEND_OACK;
fseek(fp, 0, SEEK_SET);
/* reset the last block received counter */
- last_requested_block = -1;
+ prev_sent_block = -1;
}
else
{