Skip to content

Commit 3f3da90

Browse files
committed
php#146 flock: pin task across SUSPEND to keep inline-tail flock_data alive
ASAN: heap-use-after-free in php_stdiop_set_option at the post-SUSPEND read of flock_data->result. flock_data is the inline tail of the libuv task; the scheduler's WAKER_CLEAN_EVENTS runs between worker completion and SUSPEND returning, releases the task's last ref, and libuv_task_dispose pefree's the whole region — including flock_data — before our code wakes. Fix: ADD_REF the task before SUSPEND, snapshot result/error_code into locals after SUSPEND, then RELEASE. All error paths matched. Repro: ext/async/tests/io/081-flock_non_blocking_event_loop.phpt under LINUX_X64_DEBUG_ZTS_ASAN (PR php#149 job 77702704014). Local ASAN sweep on ext/async/tests + ext/standard/tests/file + Zend/tests: 6795/6798 pass, 3 pre-existing unrelated fails (gh19983, 050/052 thread shutdown), no new UAFs.
1 parent 17dd197 commit 3f3da90

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

main/streams/plain_wrapper.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,17 +1244,26 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
12441244
return -1;
12451245
}
12461246

1247+
/* Pin task across SUSPEND: waker cleanup disposes it before SUSPEND returns,
1248+
* freeing the inline-tail flock_data we still need to read. */
1249+
ZEND_ASYNC_EVENT_ADD_REF(&task->base);
1250+
12471251
if (UNEXPECTED(!ZEND_ASYNC_SUSPEND())) {
12481252
ZEND_ASYNC_WAKER_DESTROY(coroutine);
1253+
ZEND_ASYNC_EVENT_RELEASE(&task->base);
12491254
return -1;
12501255
}
12511256

1252-
if (flock_data->result == 0) {
1257+
const int flock_result = flock_data->result;
1258+
const int flock_errno = flock_data->error_code;
1259+
ZEND_ASYNC_EVENT_RELEASE(&task->base);
1260+
1261+
if (flock_result == 0) {
12531262
data->lock_flag = value;
12541263
return 0;
12551264
}
12561265

1257-
errno = flock_data->error_code;
1266+
errno = flock_errno;
12581267
return -1;
12591268
}
12601269

0 commit comments

Comments
 (0)