https://github.com/torvalds/linux
Revision 4c5640cb5f5a6fd780d99397eca028b575cb1206 authored by David Meybohm on 22 August 2005, 20:11:08 UTC, committed by Linus Torvalds on 23 August 2005, 18:44:29 UTC
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>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent 3f024c1
History
Tip revision: 4c5640cb5f5a6fd780d99397eca028b575cb1206 authored by David Meybohm on 22 August 2005, 20:11:08 UTC
[PATCH] preempt race in getppid
Tip revision: 4c5640c
File Mode Size
adfs
affs
afs
autofs
autofs4
befs
bfs
cifs
coda
cramfs
debugfs
devfs
devpts
efs
exportfs
ext2
ext3
fat
freevxfs
hfs
hfsplus
hostfs
hpfs
hppfs
hugetlbfs
isofs
jbd
jffs
jffs2
jfs
lockd
minix
msdos
ncpfs
nfs
nfs_common
nfsd
nls
ntfs
openpromfs
partitions
proc
qnx4
ramfs
reiserfs
romfs
smbfs
sysfs
sysv
udf
ufs
umsdos
vfat
xfs
Kconfig -rw-r--r-- 63.6 KB
Kconfig.binfmt -rw-r--r-- 5.3 KB
Makefile -rw-r--r-- 3.1 KB
aio.c -rw-r--r-- 43.6 KB
attr.c -rw-r--r-- 4.4 KB
bad_inode.c -rw-r--r-- 2.8 KB
binfmt_aout.c -rw-r--r-- 14.9 KB
binfmt_elf.c -rw-r--r-- 45.3 KB
binfmt_elf_fdpic.c -rw-r--r-- 30.3 KB
binfmt_em86.c -rw-r--r-- 2.8 KB
binfmt_flat.c -rw-r--r-- 25.8 KB
binfmt_misc.c -rw-r--r-- 15.6 KB
binfmt_script.c -rw-r--r-- 2.7 KB
binfmt_som.c -rw-r--r-- 7.7 KB
bio.c -rw-r--r-- 25.4 KB
block_dev.c -rw-r--r-- 21.7 KB
buffer.c -rw-r--r-- 81.7 KB
char_dev.c -rw-r--r-- 9.5 KB
compat.c -rw-r--r-- 47.1 KB
compat_ioctl.c -rw-r--r-- 85.0 KB
dcache.c -rw-r--r-- 44.1 KB
dcookies.c -rw-r--r-- 6.2 KB
direct-io.c -rw-r--r-- 34.5 KB
dnotify.c -rw-r--r-- 4.3 KB
dquot.c -rw-r--r-- 51.7 KB
eventpoll.c -rw-r--r-- 43.9 KB
exec.c -rw-r--r-- 34.6 KB
fcntl.c -rw-r--r-- 13.1 KB
fifo.c -rw-r--r-- 3.2 KB
file.c -rw-r--r-- 5.5 KB
file_table.c -rw-r--r-- 5.9 KB
filesystems.c -rw-r--r-- 5.2 KB
fs-writeback.c -rw-r--r-- 19.4 KB
inode.c -rw-r--r-- 35.8 KB
inotify.c -rw-r--r-- 26.3 KB
ioctl.c -rw-r--r-- 3.9 KB
ioprio.c -rw-r--r-- 3.5 KB
libfs.c -rw-r--r-- 15.2 KB
locks.c -rw-r--r-- 54.9 KB
mbcache.c -rw-r--r-- 18.2 KB
mpage.c -rw-r--r-- 20.6 KB
namei.c -rw-r--r-- 60.4 KB
namespace.c -rw-r--r-- 34.9 KB
nfsctl.c -rw-r--r-- 2.5 KB
open.c -rw-r--r-- 23.0 KB
pipe.c -rw-r--r-- 18.1 KB
posix_acl.c -rw-r--r-- 8.6 KB
quota.c -rw-r--r-- 8.6 KB
quota_v1.c -rw-r--r-- 5.7 KB
quota_v2.c -rw-r--r-- 20.1 KB
read_write.c -rw-r--r-- 15.7 KB
readdir.c -rw-r--r-- 6.7 KB
select.c -rw-r--r-- 12.2 KB
seq_file.c -rw-r--r-- 9.5 KB
stat.c -rw-r--r-- 9.2 KB
super.c -rw-r--r-- 20.1 KB
xattr.c -rw-r--r-- 10.4 KB
xattr_acl.c -rw-r--r-- 2.3 KB

back to top