Skip to content

Commit bf13b72

Browse files
committed
Fix listener publication race in socket driver
That commit fixed the close-time double-unlink/use-after-free race in generic_unix listener teardown. This change addresses a separate race in listener registration, where a listener could become visible to the event loop before socket_data published the corresponding pointer. Both fixes are needed; this patch complements the earlier teardown fix rather than replacing it. Fix a race in the generic_unix socket driver where newly created listeners were registered in the global listener list before the corresponding socket_data->{active,passive}_listener pointer was published. If the event loop processed the listener in that window, the callback could consume, free, or replace the listener before the socket driver stored the pointer. The later assignment then left socket_data pointing at stale listener memory, which could surface as random hangs or corruption in gen_tcp tests, including timeouts waiting for the server helper process to start. Publish the listener pointer before calling sys_register_listener in all affected paths: active UDP receive listener setup active TCP receive listener setup passive recv/recvfrom listener setup accept listener setup This complements the earlier close-path fix by removing another generic_unix listener lifecycle race. Signed-off-by: Peter M <petermm@gmail.com>
1 parent 34a3287 commit bf13b72

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

src/platforms/generic_unix/lib/socket_driver.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ static term init_udp_socket(Context *ctx, SocketDriverData *socket_data, term pa
255255
listener->base.handler = active_recvfrom_callback;
256256
listener->buf_size = socket_data->buffer;
257257
listener->process_id = ctx->process_id;
258-
sys_register_listener(glb, &listener->base);
259258
socket_data->active_listener = listener;
259+
sys_register_listener(glb, &listener->base);
260260
}
261261
}
262262
return ret;
@@ -340,8 +340,8 @@ static term init_client_tcp_socket(Context *ctx, SocketDriverData *socket_data,
340340
listener->base.handler = active_recv_callback;
341341
listener->buf_size = socket_data->buffer;
342342
listener->process_id = ctx->process_id;
343-
sys_register_listener(glb, &listener->base);
344343
socket_data->active_listener = listener;
344+
sys_register_listener(glb, &listener->base);
345345
}
346346
}
347347
return ret;
@@ -1017,8 +1017,8 @@ static void do_recv(Context *ctx, term pid, term ref, term length, term timeout,
10171017
listener->length = term_to_int(length);
10181018
listener->buffer = socket_data->buffer;
10191019
listener->ref_ticks = term_to_ref_ticks(ref);
1020-
sys_register_listener(glb, &listener->base);
10211020
socket_data->passive_listener = listener;
1021+
sys_register_listener(glb, &listener->base);
10221022
}
10231023

10241024
void socket_driver_do_recvfrom(Context *ctx, term pid, term ref, term length, term timeout)
@@ -1119,8 +1119,8 @@ void socket_driver_do_accept(Context *ctx, term pid, term ref, term timeout)
11191119
listener->length = 0;
11201120
listener->buffer = 0;
11211121
listener->ref_ticks = term_to_ref_ticks(ref);
1122-
sys_register_listener(glb, &listener->base);
11231122
socket_data->passive_listener = listener;
1123+
sys_register_listener(glb, &listener->base);
11241124
}
11251125

11261126
static NativeHandlerResult socket_consume_mailbox(Context *ctx)

0 commit comments

Comments
 (0)