sys_getppid oopses on debug kernel (v2)
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; }
Quoted 4 lines · Kirill Korotaev
sys_getppid()optimization can access a freed memory. On kernels withDEBUG_SLABturned 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