| Avoid assigning thread data outside of mutex lock |
| |
| Patch originally from OpenSUSE: |
| https://build.opensuse.org/package/show?package=atftp&project=openSUSE%3A12.2 |
| |
| Upstream-Status: Pending |
| |
| Index: git/tftpd_list.c |
| =================================================================== |
| --- git.orig/tftpd_list.c 2012-10-24 21:48:47.000000000 -0700 |
| +++ git/tftpd_list.c 2012-10-24 21:52:04.266205076 -0700 |
| @@ -49,11 +49,11 @@ |
| */ |
| int tftpd_list_add(struct thread_data *new) |
| { |
| - struct thread_data *current = thread_data; |
| + struct thread_data *current; |
| int ret; |
| |
| pthread_mutex_lock(&thread_list_mutex); |
| - |
| + current = thread_data; |
| number_of_thread++; |
| |
| ret = number_of_thread; |
| @@ -81,11 +81,13 @@ |
| */ |
| int tftpd_list_remove(struct thread_data *old) |
| { |
| - struct thread_data *current = thread_data; |
| + struct thread_data *current; |
| int ret; |
| |
| pthread_mutex_lock(&thread_list_mutex); |
| |
| + current = thread_data; |
| + |
| number_of_thread--; |
| ret = number_of_thread; |
| |
| @@ -137,23 +139,26 @@ |
| struct thread_data *data, |
| struct client_info *client) |
| { |
| - struct thread_data *current = thread_data; /* head of the list */ |
| - struct tftp_opt *tftp_options = data->tftp_options; |
| + struct thread_data *current; /* head of the list */ |
| + struct tftp_opt *tftp_options; |
| struct client_info *tmp; |
| char options[MAXLEN]; |
| char string[MAXLEN]; |
| char *index; |
| int len; |
| |
| + /* lock the whole list before walking it */ |
| + pthread_mutex_lock(&thread_list_mutex); |
| + |
| *thread = NULL; |
| |
| + current = thread_data; |
| + tftp_options = data->tftp_options; |
| + |
| opt_request_to_string(tftp_options, options, MAXLEN); |
| index = strstr(options, "multicast"); |
| len = (int)index - (int)options; |
| |
| - /* lock the whole list before walking it */ |
| - pthread_mutex_lock(&thread_list_mutex); |
| - |
| while (current) |
| { |
| if (current != data) |
| @@ -214,9 +219,10 @@ |
| void tftpd_clientlist_remove(struct thread_data *thread, |
| struct client_info *client) |
| { |
| - struct client_info *tmp = thread->client_info; |
| + struct client_info *tmp; |
| |
| pthread_mutex_lock(&thread->client_mutex); |
| + tmp = thread->client_info; |
| while ((tmp->next != client) && (tmp->next != NULL)) |
| tmp = tmp->next; |
| if (tmp->next == NULL) |
| @@ -231,9 +237,11 @@ |
| void tftpd_clientlist_free(struct thread_data *thread) |
| { |
| struct client_info *tmp; |
| - struct client_info *head = thread->client_info; |
| + struct client_info *head; |
| |
| pthread_mutex_lock(&thread->client_mutex); |
| + head = thread->client_info; |
| + |
| while (head) |
| { |
| tmp = head; |
| @@ -250,9 +258,10 @@ |
| struct client_info *client, |
| struct sockaddr_storage *sock) |
| { |
| - struct client_info *head = thread->client_info; |
| + struct client_info *head; |
| |
| pthread_mutex_lock(&thread->client_mutex); |
| + head = thread->client_info; |
| |
| if (client) |
| { |
| @@ -334,10 +343,10 @@ |
| |
| void tftpd_list_kill_threads(void) |
| { |
| - struct thread_data *current = thread_data; /* head of list */ |
| + struct thread_data *current; /* head of list */ |
| |
| pthread_mutex_lock(&thread_list_mutex); |
| - |
| + current = thread_data; |
| |
| while (current != NULL) |
| { |
| Index: git/tftpd_mcast.c |
| =================================================================== |
| --- git.orig/tftpd_mcast.c 2012-10-24 21:48:47.000000000 -0700 |
| +++ git/tftpd_mcast.c 2012-10-24 21:49:11.570201582 -0700 |
| @@ -51,9 +51,11 @@ |
| */ |
| int tftpd_mcast_get_tid(char **addr, short *port) |
| { |
| - struct tid *current = tid_list; |
| + struct tid *current; |
| |
| pthread_mutex_lock(&mcast_tid_list); |
| + current = tid_list; |
| + |
| /* walk the list for a free tid */ |
| while (current != NULL) |
| { |
| @@ -74,9 +76,11 @@ |
| |
| int tftpd_mcast_free_tid(char *addr, short port) |
| { |
| - struct tid *current = tid_list; |
| + struct tid *current; |
| |
| pthread_mutex_lock(&mcast_tid_list); |
| + current = tid_list; |
| + |
| while (current != NULL) |
| { |
| if ((current->used == 1) && (current->port == port) && |