]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: fix incorrect thread management
authorIgor Ryzhov <iryzhov@nfware.com>
Wed, 6 Oct 2021 14:35:07 +0000 (17:35 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Wed, 6 Oct 2021 16:13:12 +0000 (19:13 +0300)
The current code passes an address of a local variable to `thread_add_read`
which stores it into `thread->ref` by the lib. The next time the thread
callback is executed, the lib stores NULL into the `thread->ref` which
means it writes into some random memory on the stack.

To fix this, we should pass a pointer to the vector entry to the lib.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
lib/resolver.c
lib/vector.c
lib/vector.h

index c2153e0a5e4481444e129e252a2ec3269c54c052..4aba909f2555b758ddaae00261dab0d4705bdf20 100644 (file)
@@ -53,14 +53,14 @@ static int resolver_cb_socket_readable(struct thread *t)
 {
        struct resolver_state *r = THREAD_ARG(t);
        int fd = THREAD_FD(t);
+       struct thread **t_ptr;
 
        vector_set_index(r->read_threads, fd, THREAD_RUNNING);
        ares_process_fd(r->channel, fd, ARES_SOCKET_BAD);
        if (vector_lookup(r->read_threads, fd) == THREAD_RUNNING) {
-               t = NULL;
+               t_ptr = (struct thread **)vector_get_index(r->read_threads, fd);
                thread_add_read(r->master, resolver_cb_socket_readable, r, fd,
-                               &t);
-               vector_set_index(r->read_threads, fd, t);
+                               t_ptr);
        }
        resolver_update_timeouts(r);
 
@@ -71,14 +71,14 @@ static int resolver_cb_socket_writable(struct thread *t)
 {
        struct resolver_state *r = THREAD_ARG(t);
        int fd = THREAD_FD(t);
+       struct thread **t_ptr;
 
        vector_set_index(r->write_threads, fd, THREAD_RUNNING);
        ares_process_fd(r->channel, ARES_SOCKET_BAD, fd);
        if (vector_lookup(r->write_threads, fd) == THREAD_RUNNING) {
-               t = NULL;
+               t_ptr = (struct thread **)vector_get_index(r->write_threads, fd);
                thread_add_write(r->master, resolver_cb_socket_writable, r, fd,
-                                &t);
-               vector_set_index(r->write_threads, fd, t);
+                                t_ptr);
        }
        resolver_update_timeouts(r);
 
@@ -105,14 +105,15 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable,
                           int writable)
 {
        struct resolver_state *r = (struct resolver_state *)data;
-       struct thread *t;
+       struct thread *t, **t_ptr;
 
        if (readable) {
-               t = vector_lookup_ensure(r->read_threads, fd);
+               t = vector_lookup(r->read_threads, fd);
                if (!t) {
+                       t_ptr = (struct thread **)vector_get_index(
+                               r->read_threads, fd);
                        thread_add_read(r->master, resolver_cb_socket_readable,
-                                       r, fd, &t);
-                       vector_set_index(r->read_threads, fd, t);
+                                       r, fd, t_ptr);
                }
        } else {
                t = vector_lookup(r->read_threads, fd);
@@ -125,11 +126,12 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable,
        }
 
        if (writable) {
-               t = vector_lookup_ensure(r->write_threads, fd);
+               t = vector_lookup(r->write_threads, fd);
                if (!t) {
+                       t_ptr = (struct thread **)vector_get_index(
+                               r->write_threads, fd);
                        thread_add_read(r->master, resolver_cb_socket_writable,
-                                       r, fd, &t);
-                       vector_set_index(r->write_threads, fd, t);
+                                       r, fd, t_ptr);
                }
        } else {
                t = vector_lookup(r->write_threads, fd);
index 565c49fd59a1802cbc4a2e1b7976b8dc656f37bb..4af564a82ff8de47b4cce02a3f12dbf3fba7b9b1 100644 (file)
@@ -123,6 +123,17 @@ int vector_set_index(vector v, unsigned int i, void *val)
        return i;
 }
 
+/* Make a specified index slot active and return its address. */
+void **vector_get_index(vector v, unsigned int i)
+{
+       vector_ensure(v, i);
+
+       if (v->active <= i)
+               v->active = i + 1;
+
+       return &v->index[i];
+}
+
 /* Look up vector.  */
 void *vector_lookup(vector v, unsigned int i)
 {
index d5857eb599d079c625efb47e27bd2277836b5d98..845c8d8b04ef62f9f626385e1dfb7f783d2a26a5 100644 (file)
@@ -54,6 +54,7 @@ extern void vector_ensure(vector v, unsigned int num);
 extern int vector_empty_slot(vector v);
 extern int vector_set(vector v, void *val);
 extern int vector_set_index(vector v, unsigned int i, void *val);
+extern void **vector_get_index(vector v, unsigned int i);
 extern void vector_unset(vector v, unsigned int i);
 extern void vector_unset_value(vector v, void *val);
 extern void vector_remove(vector v, unsigned int ix);