Skip to contentSkip to conversation

sys_getppid oopses on debug kernel (v2)

PATCH In review Kirill Korotaev 2 participants 2 messages Aug 8, 2006

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 sys_getppid oopses on debug kernel (v2)

sys_getppid() optimization can access a freed memory. On kernels with DEBUG_SLAB turned ON, this results in Oops. As Dave Hansen noted, this optimization is also unsafe for memory hotplug.

So this patch always takes the lock to be safe.

kernel/timer.c renamed from kernel/timer.c.ppiddbg +0 -0
@@ -1342,28 +1342,11 @@ asmlinkage long sys_getpid(void)

asmlinkage long sys_getppid(void)

{
	int pid;

- struct task_struct *me = current;
- struct task_struct *parent;

- parent = me->group_leader->real_parent;
- for (;;) {
- pid = parent->tgid;
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) -{
- struct task_struct *old = parent;
+ read_lock(&tasklist_lock);
+ pid = current->group_leader->real_parent->tgid;
+ read_unlock(&tasklist_lock);

- /*
- * 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;
}
#1 lore raw
Quoted 4 lines · Kirill Korotaev

sys_getppid() optimization can access a freed memory. On kernels with DEBUG_SLAB turned ON, this results in Oops. As Dave Hansen noted, this optimization is also unsafe for memory hotplug.

Yeah, I just tried coding up something to do a seqlock to note when tasks are freed, but it doesn't work. Unless somebody is really going crazy with getppid() on a very large system, this should be just fine.

-- Dave