# 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