File atftp-0.7-server_receive_race.patch of Package atftp

Index: tftpd_file.c
===================================================================
--- tftpd_file.c.orig	2012-08-06 10:26:36.356745154 +0200
+++ tftpd_file.c	2012-08-06 11:27:59.265571512 +0200
@@ -113,7 +113,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;
@@ -143,18 +143,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)
      {
@@ -171,7 +159,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;
@@ -188,7 +175,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;
           }
 
@@ -198,7 +184,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;
@@ -209,7 +194,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);
@@ -342,6 +326,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)
@@ -369,13 +367,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;
openSUSE Build Service is sponsored by