Bug 218598

Summary: pwait deadlocks on its own pid
Product: Base System Reporter: Dan McGregor <dan.mcgregor>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: 0mp, bdrewery, emaste, jilles, op, pstef
Priority: --- Keywords: patch
Version: CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
Patch to not wait on our own pid. none

Description Dan McGregor 2017-04-12 16:23:33 UTC
Created attachment 181726 [details]
Patch to not wait on our own pid.

pwait will deadlock when passed its own PID. I experienced this when kern.randompid was set with poudriere. The code was more or less this:

#!/bin/sh
do_the_thing&
pwait $!
do_the_other_thing

if do_the_thing ends before pwait starts, and do_the_thing and pwait get the same pid, pwait waits indefinitely.

I've attached a patch to warn and exit immediately if pwait is told to wait on its own pid.
Comment 1 Jilles Tjoelker freebsd_committer freebsd_triage 2017-04-12 22:02:23 UTC
Hmm, this is sort of a workaround for the shell reaping zombies quickly and not providing the script with a good way to detect this.

If code is executed like
  sh -c '...; exec pwait $$'
it arguably should deadlock.

The patch seems a simple way to avoid the deadlock in poudriere, though.
Comment 2 Dan McGregor 2017-04-20 15:59:50 UTC
(In reply to Jilles Tjoelker from comment #1)

Yeah, a literal reading of the documentation implies that it should hang. Personally I'd interpret pwait's own PID as invalid, though that's up for debate.
Comment 3 op 2017-09-23 20:25:37 UTC
Is there any update regarding on this bug?
Comment 4 Mateusz Piotrowski freebsd_committer freebsd_triage 2021-01-20 13:07:30 UTC
A similar patch got submitted to Phabricator: https://reviews.freebsd.org/D28240
Comment 5 commit-hook freebsd_committer freebsd_triage 2021-01-21 21:37:36 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=5bdce6ff546e00673f9f515d2165d02901e858aa

commit 5bdce6ff546e00673f9f515d2165d02901e858aa
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2021-01-21 21:26:15 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2021-01-21 21:36:37 +0000

    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

 bin/pwait/pwait.1 | 6 +++++-
 bin/pwait/pwait.c | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)