SHA256
1
0
forked from pool/atftp
atftp/atftp-0.7-server_receive_race.patch
2013-11-15 11:54:26 +00:00

103 lines
4.0 KiB
Diff

Index: tftpd_file.c
===================================================================
--- tftpd_file.c.orig
+++ tftpd_file.c
@@ -114,7 +114,7 @@ int tftpd_receive_file(struct thread_dat
struct sockaddr_in *sa = &data->client_info->client;
struct sockaddr_in from;
struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer;
- FILE *fp;
+ FILE *fp = NULL;
char filename[MAXLEN];
char string[MAXLEN];
int timeout = data->timeout;
@@ -144,18 +144,6 @@ int tftpd_receive_file(struct thread_dat
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 +160,6 @@ int tftpd_receive_file(struct thread_dat
if (data->trace)
logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", EOPTNEG,
tftp_errmsg[EOPTNEG]);
- fclose(fp);
return ERR;
}
timeout = result;
@@ -189,7 +176,6 @@ int tftpd_receive_file(struct thread_dat
if (data->trace)
logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", EOPTNEG,
tftp_errmsg[EOPTNEG]);
- fclose(fp);
return ERR;
}
@@ -199,7 +185,6 @@ int tftpd_receive_file(struct thread_dat
if (data->data_buffer == NULL)
{
logger(LOG_ERR, "memory allocation failure");
- fclose(fp);
return ERR;
}
tftphdr = (struct tftphdr *)data->data_buffer;
@@ -210,7 +195,6 @@ int tftpd_receive_file(struct thread_dat
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);
@@ -343,6 +327,20 @@ int tftpd_receive_file(struct thread_dat
}
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 = ntohs(tftphdr->th_block);
if (data->trace)
@@ -370,13 +368,13 @@ int tftpd_receive_file(struct thread_dat
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;