From d1f7e96f821089224ddcacf8e8f506f99c54eb5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= Date: Fri, 18 Feb 2022 19:27:13 +0100 Subject: [PATCH] test: loop: add test for destroying source of thread loop Add test which tries to destroy an active source precisely after the loop has returned from polling but has not yet acquired the thread loop lock. --- test/test-loop.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/test-loop.c b/test/test-loop.c index 98b2add09..81f7a117c 100644 --- a/test/test-loop.c +++ b/test/test-loop.c @@ -227,11 +227,45 @@ PWTEST(pwtest_loop_recurse2) return PWTEST_PASS; } +PWTEST(thread_loop_destroy_between_poll_and_lock) +{ + pw_init(NULL, NULL); + + struct pw_thread_loop *thread_loop = pw_thread_loop_new("uaf", NULL); + pwtest_ptr_notnull(thread_loop); + + struct pw_loop *loop = pw_thread_loop_get_loop(thread_loop); + pwtest_ptr_notnull(loop); + + int evfd = eventfd(0, 0); + pwtest_errno_ok(evfd); + + struct spa_source *source = pw_loop_add_io(loop, evfd, SPA_IO_IN, true, NULL, NULL); + pwtest_ptr_notnull(source); + + pw_thread_loop_start(thread_loop); + + pw_thread_loop_lock(thread_loop); + { + write(evfd, &(uint64_t){1}, sizeof(uint64_t)); + sleep(1); + pw_loop_destroy_source(loop, source); + } + pw_thread_loop_unlock(thread_loop); + + pw_thread_loop_destroy(thread_loop); + + pw_deinit(); + + return PWTEST_PASS; +} + PWTEST_SUITE(support) { pwtest_add(pwtest_loop_destroy2, PWTEST_NOARG); pwtest_add(pwtest_loop_recurse1, PWTEST_NOARG); pwtest_add(pwtest_loop_recurse2, PWTEST_NOARG); + pwtest_add(thread_loop_destroy_between_poll_and_lock, PWTEST_NOARG); return PWTEST_PASS; }