ll_queue: queue_waiter_cancel отменяет отложенный call_soon при internal==NULL (фикс UAF waiter_defer)
This commit is contained in:
1 parent
f6e6e2c73f
commit
44d4265084
2 files changed
+34
-2
No files matched your search
@@ -281,6 +281,32 @@ static void test_waiter_cancel(void) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
static void test_waiter_cancel_deferred(void) {
|
||||
TEST("waiter cancel deferred call_soon (internal==NULL)");
|
||||
struct UASYNC *ua = uasync_create();
|
||||
struct ll_queue *q = queue_new(ua, 0, 0, 0, "wcd");
|
||||
queue_set_threshold(q, 0, 0);
|
||||
queue_set_waiter_defer(q, 1);
|
||||
|
||||
int called = 0;
|
||||
struct queue_waiter_handle h = {0};
|
||||
int ret = queue_waiter_wait(q, &h, waiter_cb, &called);
|
||||
ASSERT(ret == 1, "immediate branch (empty queue)");
|
||||
ASSERT(h.internal == NULL, "no waiter registered (deferred path)");
|
||||
ASSERT(h.call_soon_id != NULL, "deferred call scheduled");
|
||||
|
||||
/* До фикса: queue_waiter_cancel выходил по !internal, call_soon_id оставался
|
||||
* висеть и deferred-колбэк срабатывал позже (UAF после teardown). */
|
||||
queue_waiter_cancel(q, &h);
|
||||
ASSERT(h.call_soon_id == NULL, "call_soon_id cleared by cancel");
|
||||
|
||||
for (int i = 0; i < 10; i++) uasync_poll(ua, 1);
|
||||
ASSERT_EQ(called, 0, "deferred callback cancelled (did not fire)");
|
||||
|
||||
queue_free(q); uasync_destroy(ua, 0);
|
||||
PASS();
|
||||
}
|
||||
|
||||
static void test_waiter_queue_free(void) {
|
||||
TEST("queue_free clears waiters");
|
||||
struct UASYNC *ua = uasync_create();
|
||||
@@ -454,6 +480,7 @@ int main(void) {
|
||||
test_waiter();
|
||||
test_waiter_multiple();
|
||||
test_waiter_cancel();
|
||||
test_waiter_cancel_deferred();
|
||||
test_waiter_queue_free();
|
||||
test_waiter_threshold();
|
||||
test_waiter_reuse();
|
||||
|
||||
Reference in new issue
Block a user