On 02/20, Eric W. Biederman wrote:
quoted hunk ↗ jump to hunk
+void exchange_tids(struct task_struct *ntask, struct task_struct *otask)
+{
+ /* pid_links[PIDTYPE_PID].next is always NULL */
+ struct pid *npid = READ_ONCE(ntask->thread_pid);
+ struct pid *opid = READ_ONCE(otask->thread_pid);
+
+ rcu_assign_pointer(opid->tasks[PIDTYPE_PID].first, &ntask->pid_links[PIDTYPE_PID]);
+ rcu_assign_pointer(npid->tasks[PIDTYPE_PID].first, &otask->pid_links[PIDTYPE_PID]);
+ rcu_assign_pointer(ntask->thread_pid, opid);
+ rcu_assign_pointer(otask->thread_pid, npid);
this breaks has_group_leader_pid()...
proc_pid_readdir() can miss a process doing mt-exec but this looks fixable,
just we need to update ntask->thread_pid before updating ->first.
The more problematic case is __exit_signal() which does
if (unlikely(has_group_leader_pid(tsk)))
posix_cpu_timers_exit_group(tsk);
Oleg.