Messages in this thread Patch in this message | | | Date | Fri, 19 Aug 2005 08:03:14 -0400 | From | David Meybohm <> | Subject | [PATCH] preempt race in getppid |
| |
With CONFIG_PREEMPT && !CONFIG_SMP, it's possible for sys_getppid to return a bogus value if the parent's task_struct gets reallocated after current->group_leader->real_parent is read:
asmlinkage long sys_getppid(void) { int pid; struct task_struct *me = current; struct task_struct *parent;
parent = me->group_leader->real_parent; RACE HERE => for (;;) { pid = parent->tgid; #ifdef CONFIG_SMP { struct task_struct *old = parent;
/* * Make sure we read the pid before re-reading the * parent pointer: */ smp_rmb(); parent = me->group_leader->real_parent; if (old != parent) continue; } #endif break; } return pid; }
If the process gets preempted at the indicated point, the parent process can go ahead and call exit() and then get wait()'d on to reap its task_struct. When the preempted process gets resumed, it will not do any further checks of the parent pointer on !CONFIG_SMP: it will read the bad pid and return.
So, the same algorithm used when SMP is enabled should be used when preempt is enabled, which will recheck ->real_parent in this case.
Signed-off-by: David Meybohm <dmeybohmlkml@bellsouth.net> ---
kernel/timer.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
Index: v2.6/kernel/timer.c =================================================================== --- v2.6.orig/kernel/timer.c 2005-08-19 07:29:29.000000000 -0400 +++ v2.6/kernel/timer.c 2005-08-19 07:31:25.000000000 -0400 @@ -999,7 +999,7 @@ asmlinkage long sys_getppid(void) parent = me->group_leader->real_parent; for (;;) { pid = parent->tgid; -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) { struct task_struct *old = parent; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |