Clear current before calling proc_decref()
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 25 Sep 2018 01:19:37 +0000 (21:19 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 25 Sep 2018 01:19:37 +0000 (21:19 -0400)
commit38346732733e32e6ae07b370634c33643280771f
tree7ad25e2b9d07cfbf61c11e1e5454259eef72100b
parent3957e726d0cbaeb42fe8c1e5efffaba5ef0b00d6
Clear current before calling proc_decref()

'current,' aka pcpui->cur_proc, is a counted reference that is viewable
from code other than the code that is clearing the ref.  Even though
it's a per-core data structure, it's just like a ref in a global data
structure.

In this case, if you decref current when you are not guaranteed to have
an extra ref, you could have dropped the final reference.  Anyone who
uses 'current' after that is basically a use-after-free bug.

Here's a specific backtrace of the bug.  A process was exiting and the
final ref was dropped in __abandon_core(), but not cleared from current.
The process had a chan that was decreffed in __proc_free(), and that
chan eventually needed to block.  sem_down() saw 'current' and attempted
to save a reference to it, even though the process was basically freed.

 Stack Backtrace on Core 0:
 #01 [<0xffffffffc200a00c>] in backtrace
 #02 [<0xffffffffc20097fd>] in _panic
 #03 [<0xffffffffc2048ef6>] in kref_get
 #04 [<0xffffffffc200ba71>] in sem_down
 #05 [<0xffffffffc200bdbb>] in sem_down_bulk
 #06 [<0xffffffffc2050189>] in rcu_barrier
 #07 [<0xffffffffc2041ec6>] in tf_dfs_purge
 #08 [<0xffffffffc2041f90>] in tf_dfs_purge
 #09 [<0xffffffffc2041f90>] in tf_dfs_purge
 #10 [<0xffffffffc2041f90>] in tf_dfs_purge
 #11 [<0xffffffffc2041f90>] in tf_dfs_purge
 #12 [<0xffffffffc2079050>] in gtfs_release
 #13 [<0xffffffffc2078deb>] in kref_put
 #14 [<0xffffffffc20315d0>] in chan_release
 #15 [<0xffffffffc2030cfb>] in kref_put
 #16 [<0xffffffffc2048b1a>] in __proc_free
 #17 [<0xffffffffc2048a6b>] in kref_put
 #18 [<0xffffffffc20a6f21>] in __abandon_core
 #19 [<0xffffffffc204c8b9>] in abandon_core
 #20 [<0xffffffffc20539cd>] in __smp_idle

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/riscv/process.c
kern/arch/x86/process64.c
kern/src/kthread.c
kern/src/process.c