Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

pid: check init is created first after idr alloc

This moves the condition (tid != 1 && !tmp->child_reaper) to after idr
alloc, so it not only covers that first process in pid namespace has pid
1 in case of clone3(set_tid) requesting wrong pid, but also if idr
itself gives wrong pid for some reason.

This could've been the case before this patch, when creating first
process the alloc_pid()->pidfs_add_pid() code path fails, so that the
idr->idr_next is non zero anymore and next process calling to
alloc_pid(), will get 2 as a pid from idr_alloc_cyclic(). Though thanks
to PIDNS_ADDING logic, free_pid() disables further pid allocation in
this case and it does not lead to any real problem.

Note: This is also a preparation for the next patch in the series, which
will introduce an ability of creating init from the task different to
the task which had created the pid namespace. Needed to make sure that
init is always first, even in this new case.

--

Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Link: https://patch.msgid.link/20260318122157.280595-3-ptikhomirov@virtuozzo.com
v3: Split from main commit. Merge two checks of ->child_reaper into one.
v4: Update commit message about PIDNS_ADDING.
v5: Add Andrei's review tag.
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Pavel Tikhomirov and committed by
Christian Brauner
39c8806e d9c857ae

+10 -7
+10 -7
kernel/pid.c
··· 215 215 retval = -EINVAL; 216 216 if (tid < 1 || tid >= pid_max[ns->level - i]) 217 217 goto out_abort; 218 - /* 219 - * Also fail if a PID != 1 is requested and 220 - * no PID 1 exists. 221 - */ 222 - if (tid != 1 && !READ_ONCE(tmp->child_reaper)) 223 - goto out_abort; 224 218 retval = -EPERM; 225 219 if (!checkpoint_restore_ns_capable(tmp->user_ns)) 226 220 goto out_abort; ··· 290 296 291 297 pid->numbers[i].nr = nr; 292 298 pid->numbers[i].ns = tmp; 293 - tmp = tmp->parent; 294 299 i--; 295 300 retried_preload = false; 301 + 302 + /* 303 + * PID 1 (init) must be created first. 304 + */ 305 + if (!READ_ONCE(tmp->child_reaper) && nr != 1) { 306 + retval = -EINVAL; 307 + goto out_free; 308 + } 309 + 310 + tmp = tmp->parent; 296 311 } 297 312 298 313 /*