summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2001-11-13 04:16:12 +0000
committerhpa <hpa>2001-11-13 04:16:12 +0000
commitd2206bf9b9b0fe7ae0d6fd4c08ca85132340620a (patch)
treea235f69c6ff4ca96f4976996334570f2a89e02d0
parenta58b9604c52694b252c73fffe5de951b0f821ea9 (diff)
downloadtftp-hpa-d2206bf9b9b0fe7ae0d6fd4c08ca85132340620a.tar.gz
Fix the Sorcerer's Apprentice bug in both the client and the server.tftp-hpa-0.25
-rw-r--r--CHANGES5
-rw-r--r--tftp/tftp.c10
-rw-r--r--tftpd/tftpd.c9
3 files changed, 16 insertions, 8 deletions
diff --git a/CHANGES b/CHANGES
index 2ae9114..15874ab 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
$Id$
+Changes in 0.25:
+ Fixed Sorcerer's Apprentice bug in both the client and the
+ server. These bugs were inherited from the original BSD code.
+
+
Changes in 0.24:
Fix bugs in both client and server dealing with block number
wraparound, usually manifesting themselves as failure to
diff --git a/tftp/tftp.c b/tftp/tftp.c
index fe8a88d..46000d4 100644
--- a/tftp/tftp.c
+++ b/tftp/tftp.c
@@ -137,7 +137,7 @@ tftp_sendfile(int fd, char *name, char *mode)
}
timeout = 0;
(void) sigsetjmp(timeoutbuf,1);
-send_data:
+
if (trace)
tpacket("sent", dp, size + 4);
n = sendto(f, dp, size + 4, 0,
@@ -184,9 +184,11 @@ send_data:
printf("discarded %d packets\n",
j);
}
- if (ap->th_block == (block-1)) {
- goto send_data;
- }
+ /*
+ * RFC1129/RFC1350: We MUST NOT re-send the DATA
+ * packet in response to an invalid ACK. Doing so
+ * would cause the Sorcerer's Apprentice bug.
+ */
}
}
if ( !is_request )
diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c
index c019591..4f700c9 100644
--- a/tftpd/tftpd.c
+++ b/tftpd/tftpd.c
@@ -978,7 +978,6 @@ tftp_sendfile(struct formats *pf, struct tftphdr *oap, int oacklen)
timeout = 0;
(void) sigsetjmp(timeoutbuf,1);
- send_data:
if (send(peer, dp, size + 4, 0) != size + 4) {
syslog(LOG_ERR, "tftpd: write: %m");
goto abort;
@@ -1005,9 +1004,11 @@ tftp_sendfile(struct formats *pf, struct tftphdr *oap, int oacklen)
}
/* Re-synchronize with the other side */
(void) synchnet(peer);
- if (ap->th_block == (block -1)) {
- goto send_data;
- }
+ /*
+ * RFC1129/RFC1350: We MUST NOT re-send the DATA
+ * packet in response to an invalid ACK. Doing so
+ * would cause the Sorcerer's Apprentice bug.
+ */
}
}