diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-03-26 02:37:42 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-03-26 02:37:42 +0100 |
commit | 9aa6573359ffad41ef197b7f83623d7cbdeca068 (patch) | |
tree | 1fd245250d7ddabd7dd138123ccabf17b77cd902 /sys/src/cmd | |
parent | 5c95c50c6c470e1b9582998796555e00a6e0d7e5 (diff) |
kernel: fix tsleep()/twakeup()/tsemacquire() race
tsleep() used to cancel the timer with:
if(up->tt != nil)
timerdel(up);
which still can result in twakeup() to fire after tsleep()
returns (because we set Timer.tt to nil *before* we call the tfn).
in most cases, this is not an issue as the Rendez*
usually is just &up->sleep, but when it is dynamically allocated
or on the stack like in tsemacquire(), twakeup() will call
wakeup() on a potentially garbage Rendez structure!
to fix the race, we execute the wakup() with the Timer lock
held, and set p->trend to nil only after we called wakeup().
that way, the timerdel(); which unconditionally locks the Timer;
can act as a proper barrier and use up->trend == nil as the
condition if the timer has already fired.
Diffstat (limited to 'sys/src/cmd')
0 files changed, 0 insertions, 0 deletions