diff options
| author | David Meybohm <[email protected]> | 2005-08-22 20:11:08 +0000 |
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2005-08-23 18:44:29 +0000 |
| commit | 4c5640cb5f5a6fd780d99397eca028b575cb1206 (patch) | |
| tree | 3f5eb4b4390ea71031eb2c93261052e6698cbdc1 /net/lapb/lapb_subr.c | |
| parent | Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 (diff) | |
| download | kernel-4c5640cb5f5a6fd780d99397eca028b575cb1206.tar.gz kernel-4c5640cb5f5a6fd780d99397eca028b575cb1206.zip | |
[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 <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Diffstat (limited to 'net/lapb/lapb_subr.c')
0 files changed, 0 insertions, 0 deletions
