# This fixes a use-after-free bug in the context switching. A process going
# out of context after exiting wakes up the next process and then kills
# itself. The problem is that when it gets around to killing itself is up to
# the host and can happen a long time later, including after the incoming
# process has freed its stack, and that memory is possibly being used for
# something else.
# The fix is to have the incoming process kill the exiting process just to
# make sure it can't be running at the point that its stack is freed.
Index: um/arch/um/kernel/tt/process_kern.c
===================================================================
--- um.orig/arch/um/kernel/tt/process_kern.c 2004-08-12 21:25:45.000000000 -0400
+++ um/arch/um/kernel/tt/process_kern.c 2004-09-14 01:41:02.000000000 -0400
@@ -27,7 +27,7 @@
void *_switch_to_tt(void *prev, void *next)
{
- struct task_struct *from, *to;
+ struct task_struct *from, *to, *prev_sched;
struct file_handle *pipe;
unsigned long flags;
int err, vtalrm, alrm, prof, cpu;
@@ -72,6 +72,17 @@
if(err != sizeof(c))
panic("read of switch_pipe failed, errno = %d", -err);
+ /* If the process that we have just scheduled away from has exited,
+ * then it needs to be killed here. The reason is that, even though
+ * it will kill itself when it next runs, that may be too late. Its
+ * stack will be freed, possibly before then, and if that happens,
+ * we have a use-after-free situation. So, it gets killed here
+ * in case it has not already killed itself.
+ */
+ prev_sched = current->thread.prev_sched;
+ if(prev_sched->state == TASK_ZOMBIE)
+ os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
+
/* This works around a nasty race with 'jail'. If we are switching
* between two threads of a threaded app and the incoming process
* runs before the outgoing process reaches the read, and it makes