aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Fandrich <dan@coneharvesters.com>2006-03-20 22:15:22 +0000
committerDan Fandrich <dan@coneharvesters.com>2006-03-20 22:15:22 +0000
commita63f9887b9523a5d73ed9348539919c175c1756a (patch)
tree04786738030d80c104aa44199f356f249cc99472
parent1282aad4a5122e391fccaee7de11f923b269ef45 (diff)
Fixed a bug whereby a received file whose length was a multiple of
512 bytes could have random garbage appended. Also, stop processing TFTP packets which are too short to be legal.
-rw-r--r--lib/tftp.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/lib/tftp.c b/lib/tftp.c
index 6560a484d..9af1cf9b5 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -656,30 +656,40 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
state->remote_addrlen = fromlen;
}
- /* The event is given by the TFTP packet time */
- event = (tftp_event_t)ntohs(state->rpacket.event);
-
- switch(event) {
- case TFTP_EVENT_DATA:
- Curl_client_write(data, CLIENTWRITE_BODY,
- (char *)state->rpacket.u.data.data, state->rbytes-4);
- break;
- case TFTP_EVENT_ERROR:
- state->error = (tftp_error_t)ntohs(state->rpacket.u.error.code);
- infof(conn->data, "%s\n", (char *)state->rpacket.u.error.data);
- break;
- case TFTP_EVENT_ACK:
- break;
- case TFTP_EVENT_RRQ:
- case TFTP_EVENT_WRQ:
- default:
- failf(conn->data, "%s\n", "Internal error: Unexpected packet");
- break;
- }
-
- /* Update the progress meter */
- Curl_pgrsUpdate(conn);
+ /* Sanity check packet length */
+ if (state->rbytes < 4)
+ {
+ failf(conn->data, "Received too short packet\n");
+ /* Not a timeout, but how best to handle it? */
+ event = TFTP_EVENT_TIMEOUT;
+ } else {
+
+ /* The event is given by the TFTP packet time */
+ event = (tftp_event_t)ntohs(state->rpacket.event);
+
+ switch(event) {
+ case TFTP_EVENT_DATA:
+ if (state->rbytes > 4)
+ Curl_client_write(data, CLIENTWRITE_BODY,
+ (char *)state->rpacket.u.data.data, state->rbytes-4);
+ break;
+ case TFTP_EVENT_ERROR:
+ state->error = (tftp_error_t)ntohs(state->rpacket.u.error.code);
+ infof(conn->data, "%s\n", (char *)state->rpacket.u.error.data);
+ break;
+ case TFTP_EVENT_ACK:
+ break;
+ case TFTP_EVENT_RRQ:
+ case TFTP_EVENT_WRQ:
+ default:
+ failf(conn->data, "%s\n", "Internal error: Unexpected packet");
+ break;
+ }
+
+ /* Update the progress meter */
+ Curl_pgrsUpdate(conn);
+ }
}
/* Check for transfer timeout every 10 blocks, or after timeout */