Skip to content

Commit 508bb6e

Browse files
committed
erts: Fix race between setup_bif_timer and suspending process
Symptom: SEGV seen one time in process_SUITE:suspend_process_pausing_bif_timer_mass Scenario: A1. Process A calls setup_bif_timer() A2. Create BIF timer A2. Lock ERTS_PROC_LOCK_BTM for receiving process B (proc) A3. Read proc->paused_bif_timers to be NULL A4. Insert timer into proc->bif_timers tree A5. Unlock ERTS_PROC_LOCK_BTM for B B6. Suspending process B calls erts_pause_bif_timers() B7. Lock ERTS_PROC_LOCK_BTM B8. Set c_p->paused_bif_timers B9. Cancel timer in c_p->bif_timers and free message buffer A10. Process A continues in setup_bif_timer() A11. Read proc->paused_bif_timers AGAIN, now set as != NULL A12. Cancel timer and crash on double free of message buffer Fix: Don't read proc->paused_bif_timers again without lock
1 parent 044244c commit 508bb6e

1 file changed

Lines changed: 9 additions & 10 deletions

File tree

erts/emulator/beam/erl_hl_timer.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,16 +1834,18 @@ setup_bif_timer(Process *c_p, int twheel, ErtsMonotonicTime timeout_pos,
18341834
Process *proc = erts_pid2proc_opt(c_p, ERTS_PROC_LOCK_MAIN,
18351835
rcvr, ERTS_PROC_LOCK_BTM,
18361836
ERTS_P2P_FLG_INC_REFC);
1837-
if (proc) {
1837+
1838+
if (proc && !proc->paused_bif_timers) {
18381839
tmr->type.head.receiver.proc = proc;
1839-
if (proc->paused_bif_timers) {
1840-
create_paused_bif_timer(tmr, proc, esdp);
1841-
} else {
1842-
proc_btm_rbt_insert(&proc->bif_timers, tmr);
1843-
}
1840+
proc_btm_rbt_insert(&proc->bif_timers, tmr);
18441841
erts_proc_unlock(proc, ERTS_PROC_LOCK_BTM);
18451842
}
1846-
if (!proc || proc->paused_bif_timers) {
1843+
else {
1844+
if (proc) {
1845+
create_paused_bif_timer(tmr, proc, esdp);
1846+
erts_proc_unlock(proc, ERTS_PROC_LOCK_BTM);
1847+
erts_proc_dec_refc(proc);
1848+
}
18471849
if (tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) {
18481850
btm_rbt_delete(&esdp->timer_service->btm_tree, tmr);
18491851
tmr->btm.tree.parent = ERTS_HLT_PFIELD_NOT_IN_TABLE;
@@ -1855,9 +1857,6 @@ setup_bif_timer(Process *c_p, int twheel, ErtsMonotonicTime timeout_pos,
18551857
else
18561858
hlt_delete_timer(esdp, &tmr->type.hlt);
18571859
timer_destroy((ErtsTimer *) tmr, twheel, 1);
1858-
if (proc) {
1859-
erts_proc_dec_refc(proc);
1860-
}
18611860
}
18621861
}
18631862

0 commit comments

Comments
 (0)