pstree: check for pid collision before switching to new sid/gid

Without this check we can hit the BUG in lookup_create_item just a few
steps later (if one thread in images has same pid with new sid/gid). And
also this check saves us from different sorts of unexpected errors on
restore (if one non-thread task in images has same pid/sid/gid already).

Fixes: #1332
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov 2021-03-01 10:55:18 +03:00 committed by Andrei Vagin
parent 1c1949ab53
commit 77968d43c3

View file

@ -339,6 +339,7 @@ static int prepare_pstree_for_shell_job(pid_t pid)
pid_t current_gid = getpgid(pid);
struct pstree_item *pi;
struct pid *tmp;
pid_t old_sid;
pid_t old_gid;
@ -371,6 +372,13 @@ static int prepare_pstree_for_shell_job(pid_t pid)
pr_info("Migrating process tree (SID %d->%d)\n",
old_sid, current_sid);
tmp = pstree_pid_by_virt(current_sid);
if (tmp) {
pr_err("Current sid %d intersects with pid (%d) in images",
current_sid, tmp->state);
return -1;
}
for_each_pstree_item(pi) {
if (pi->sid == old_sid)
pi->sid = current_sid;
@ -384,6 +392,13 @@ static int prepare_pstree_for_shell_job(pid_t pid)
pr_info("Migrating process tree (GID %d->%d)\n",
old_gid, current_gid);
tmp = pstree_pid_by_virt(current_gid);
if (tmp) {
pr_err("Current gid %d intersects with pid (%d) in images",
current_gid, tmp->state);
return -1;
}
for_each_pstree_item(pi) {
if (pi->pgid == old_gid)
pi->pgid = current_gid;