Remove deadlock in rc caused by pwait waiting for itself.

The following situation can trigger the deadlock:
1) Long time ago a_service was started through rc.d
2) We want to restart a_service and issue service a_service restart
3) rc.subr reads current process PID (via file or process),
   sends TERM signal and runs pwait with PID harvested
4) a_service process dies very quickly so it's PID becomes available.
   It is possible that while original process was running,
   PID counter overflowed and pwait got assigned a_service's PID.

This patch ignores pid(s) to wait that are equal to pwait PID.

Reported by:	Dan McGregor, Boris Lytochkin
Submitted by:	Boris Lytochkin <lytboris at gmail.com>
Reviewed By:	0mp
MFC after:	2 weeks
PR:		218598
Differential Revision: https://reviews.freebsd.org/D28240
This commit is contained in:
Alexander V. Chernikov 2021-01-21 21:26:15 +00:00
parent 1ac7c34486
commit 5bdce6ff54
2 changed files with 9 additions and 1 deletions

View file

@ -32,7 +32,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 5, 2020
.Dd January 21, 2021
.Dt PWAIT 1
.Os
.Sh NAME
@ -145,6 +145,10 @@ is not a substitute for the
.Xr wait 1
builtin
as it will not clean up any zombies or state in the parent process.
.Pp
To avoid deadlock,
.Nm
will ignore its own pid, if it is provided as a process id to wait for.
.Sh HISTORY
A
.Nm

View file

@ -146,6 +146,10 @@ main(int argc, char *argv[])
warnx("%s: bad process id", s);
continue;
}
if (pid == getpid()) {
warnx("%s: skiping my own pid", s);
continue;
}
for (i = 0; i < nleft; i++) {
if (e[i].ident == (uintptr_t)pid) {
break;