mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Fix use-after free in thread stopping code
This commit is contained in:
parent
794f555f63
commit
92d934f0d1
@ -294,6 +294,13 @@ pipe_pollin(struct pipe *p, struct pfd *pfd)
|
|||||||
BUFFER_PUSH(pfd->loop) = NULL;
|
BUFFER_PUSH(pfd->loop) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pipe_free(struct pipe *p)
|
||||||
|
{
|
||||||
|
close(p->fd[0]);
|
||||||
|
close(p->fd[1]);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
wakeup_init(struct bird_thread *loop)
|
wakeup_init(struct bird_thread *loop)
|
||||||
{
|
{
|
||||||
@ -312,6 +319,12 @@ wakeup_do_kick(struct bird_thread *loop)
|
|||||||
pipe_kick(&loop->wakeup);
|
pipe_kick(&loop->wakeup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
wakeup_free(struct bird_thread *loop)
|
||||||
|
{
|
||||||
|
pipe_free(&loop->wakeup);
|
||||||
|
}
|
||||||
|
|
||||||
static inline _Bool
|
static inline _Bool
|
||||||
birdloop_try_ping(struct birdloop *loop, u32 ltt)
|
birdloop_try_ping(struct birdloop *loop, u32 ltt)
|
||||||
{
|
{
|
||||||
@ -918,14 +931,24 @@ static void
|
|||||||
bird_thread_cleanup(void *_thr)
|
bird_thread_cleanup(void *_thr)
|
||||||
{
|
{
|
||||||
struct bird_thread *thr = _thr;
|
struct bird_thread *thr = _thr;
|
||||||
|
struct birdloop *meta = thr->meta;
|
||||||
ASSERT_DIE(birdloop_inside(&main_birdloop));
|
ASSERT_DIE(birdloop_inside(&main_birdloop));
|
||||||
|
|
||||||
/* Free the meta loop */
|
/* Wait until the thread actually finishes */
|
||||||
thr->meta->thread = NULL;
|
ASSERT_DIE(meta);
|
||||||
birdloop_free(thr->meta);
|
birdloop_enter(meta);
|
||||||
|
birdloop_leave(meta);
|
||||||
|
|
||||||
|
/* No more wakeup */
|
||||||
|
wakeup_free(thr);
|
||||||
|
|
||||||
/* Thread attributes no longer needed */
|
/* Thread attributes no longer needed */
|
||||||
pthread_attr_destroy(&thr->thread_attr);
|
pthread_attr_destroy(&thr->thread_attr);
|
||||||
|
|
||||||
|
/* Free the meta loop */
|
||||||
|
thr->meta->thread = NULL;
|
||||||
|
thr->meta = NULL;
|
||||||
|
birdloop_free(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bird_thread *
|
static struct bird_thread *
|
||||||
@ -1035,6 +1058,10 @@ bird_thread_shutdown(void * _ UNUSED)
|
|||||||
/* Leave the thread-dropper loop as we aren't going to return. */
|
/* Leave the thread-dropper loop as we aren't going to return. */
|
||||||
birdloop_leave(thread_dropper);
|
birdloop_leave(thread_dropper);
|
||||||
|
|
||||||
|
/* Last try to run the priority event list; ruin it then to be extra sure */
|
||||||
|
ev_run_list(&this_thread->priority_events);
|
||||||
|
memset(&this_thread->priority_events, 0xa5, sizeof(this_thread->priority_events));
|
||||||
|
|
||||||
/* Drop loops including the thread dropper itself */
|
/* Drop loops including the thread dropper itself */
|
||||||
while (!EMPTY_LIST(thr->loops))
|
while (!EMPTY_LIST(thr->loops))
|
||||||
{
|
{
|
||||||
@ -1054,8 +1081,8 @@ bird_thread_shutdown(void * _ UNUSED)
|
|||||||
wakeup_do_kick(SKIP_BACK(struct bird_thread, n, HEAD(group->threads)));
|
wakeup_do_kick(SKIP_BACK(struct bird_thread, n, HEAD(group->threads)));
|
||||||
UNLOCK_DOMAIN(attrs, group->domain);
|
UNLOCK_DOMAIN(attrs, group->domain);
|
||||||
|
|
||||||
/* Stop the meta loop */
|
/* Request thread cleanup from main loop */
|
||||||
birdloop_leave(thr->meta);
|
ev_send_loop(&main_birdloop, &thr->cleanup_event);
|
||||||
|
|
||||||
/* Local pages not needed anymore */
|
/* Local pages not needed anymore */
|
||||||
flush_local_pages();
|
flush_local_pages();
|
||||||
@ -1063,8 +1090,8 @@ bird_thread_shutdown(void * _ UNUSED)
|
|||||||
/* Unregister from RCU */
|
/* Unregister from RCU */
|
||||||
rcu_thread_stop(&thr->rcu);
|
rcu_thread_stop(&thr->rcu);
|
||||||
|
|
||||||
/* Request thread cleanup from main loop */
|
/* Now we can be cleaned up */
|
||||||
ev_send_loop(&main_birdloop, &thr->cleanup_event);
|
birdloop_leave(thr->meta);
|
||||||
|
|
||||||
/* Exit! */
|
/* Exit! */
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user