Fix off-by-one in open_memstream
[ust.git] / libust / tracectl.c
index bef4537dd4ffeb5311c4e83dabbf60adfbb3fbd3..0cff6fda9f035e8a009232268530e8e39e206ab4 100644 (file)
@@ -543,6 +543,11 @@ unlock_traces:
        return retval;
 }
 
+static void release_listener_mutex(void *ptr)
+{
+       pthread_mutex_unlock(&listener_thread_data_mutex);
+}
+
 static void listener_cleanup(void *ptr)
 {
        pthread_mutex_lock(&listen_sock_mutex);
@@ -952,7 +957,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header,
                print_markers(fp);
                fclose(fp);
 
-               reply_header->size = size;
+               reply_header->size = size + 1;  /* Include final \0 */
 
                result = ustcomm_send(sock, reply_header, ptr);
 
@@ -978,7 +983,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header,
                print_trace_events(fp);
                fclose(fp);
 
-               reply_header->size = size;
+               reply_header->size = size + 1;  /* Include final \0 */
 
                result = ustcomm_send(sock, reply_header, ptr);
 
@@ -1096,6 +1101,7 @@ void *listener_main(void *p)
 
                for (i = 0; i < nfds; i++) {
                        pthread_mutex_lock(&listener_thread_data_mutex);
+                       pthread_cleanup_push(release_listener_mutex, NULL);
                        epoll_sock = (struct ustcomm_sock *)events[i].data.ptr;
                        if (epoll_sock == listen_sock) {
                                addr_size = sizeof(struct sockaddr);
@@ -1124,7 +1130,7 @@ void *listener_main(void *p)
                                                           epoll_sock->fd);
                                }
                        }
-                       pthread_mutex_unlock(&listener_thread_data_mutex);
+                       pthread_cleanup_pop(1); /* release listener mutex */
                }
        }
 
@@ -1711,7 +1717,7 @@ static void ust_after_fork_common(ust_fork_info_t *fork_info)
 
 void ust_after_fork_parent(ust_fork_info_t *fork_info)
 {
-       /* Reenable signals */
+       /* Release mutexes and reenable signals */
        ust_after_fork_common(fork_info);
 }
 
@@ -1720,7 +1726,15 @@ void ust_after_fork_child(ust_fork_info_t *fork_info)
        /* First sanitize the child */
        ust_fork();
 
-       /* Then reenable interrupts */
+       /* Then release mutexes and reenable signals */
        ust_after_fork_common(fork_info);
+
+       /*
+        * Make sure we clean up the urcu-bp thread list in the child by running
+        * the garbage collection before any pthread_create can be called.
+        * Failure to do so could lead to a deadlock caused by reuse of a thread
+        * ID before urcu-bp garbage collection is performed.
+        */
+       synchronize_rcu();
 }
 
This page took 0.023627 seconds and 4 git commands to generate.