fix: set tc->sock=SOCKET_INVALID before on_error in handle_error
В одном epoll_wait batch три события для fd: EPOLLERR (освобождает tc), EPOLLIN (read_cb), EPOLLOUT (write_cb). read_cb/write_cb guard проверяет tc->sock==SOCKET_INVALID, но sock обнулялся ПОСЛЕ on_error. Перенос sock=SOCKET_INVALID до on_error защищает от use-after-free. Доказано: без фикса segfault на tcp_io.c:374 (write_cb → tc->connected). С фиксом тест работает без крашей.
This commit is contained in:
1 parent
aff3b2d00f
commit
a97a38d867
3 files changed
+627
-622
No files matched your search
@@ -1,5 +1,6 @@
|
||||
// test_uasync_socket_race.c — тест гонки fd-reuse в epoll при быстром accept/close/accept
|
||||
// 4 дочерних процесса, каждый 200 connect+send+close. Сервер на uasync+tcp_io.
|
||||
// Проверяет что нет use-after-free при двойном epoll-событии (ERROR→free tc, WRITE→stale).
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -104,9 +105,11 @@ static void test_timeout(void* arg) {
|
||||
int main(void) {
|
||||
printf("=== test_uasync_socket_race ===\n"); fflush(stdout);
|
||||
|
||||
debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR);
|
||||
debug_config_init();
|
||||
for (int i = 1; i < DEBUG_CATEGORY_COUNT; i++) debug_set_category_level(i, DEBUG_LEVEL_ERROR);
|
||||
srand((unsigned)getpid());
|
||||
close(0); open("/dev/null", O_RDONLY);
|
||||
|
||||
close(0); open("/dev/null", O_RDONLY); // резервируем fd 0
|
||||
|
||||
g_port = 25000 + (rand() % 10000);
|
||||
g_ua = uasync_create();
|
||||
@@ -122,7 +125,6 @@ int main(void) {
|
||||
if (bind(lsock, (struct sockaddr*)&la, sizeof(la)) < 0) { printf("[FAIL] bind: %s\n", strerror(errno)); goto cleanup; }
|
||||
if (listen(lsock, 32) < 0) { printf("[FAIL] listen: %s\n", strerror(errno)); goto cleanup; }
|
||||
uasync_add_socket(g_ua, lsock, on_accept_cb, NULL, NULL, NULL);
|
||||
printf(" listen fd=%d epoll ok\n", lsock); fflush(stdout);
|
||||
|
||||
for (int i = 0; i < CHILDREN; i++) {
|
||||
pid_t pid = fork();
|
||||
|
||||
Reference in new issue
Block a user