<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    Hi Thomas, Archie,<br>
    <br>
    Generally, I would agree that a bit more cleanup/resetting of the
    signal state makes sense.<br>
    There is general unease about changing this kind of global state
    that has been stable for a long time.<br>
    An application that expects to change operating system state before
    calling exec and expecting it to be retained/passed to the child is
    expecting too much. <br>
    <br>
    A change here should also be reviewed by Hotspot, signals are a
    sensitive area for them too.<br>
    <br>
    Regards, Roger<br>
    <br>
    <div class="moz-cite-prefix">On 4/29/25 10:55 AM, Thomas Stüfe
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAA-vtUw14HjNLwVitGofTBN_K6yJ4nB7tzyBdymiKb5P_7sGag@mail.gmail.com">
      
      <div dir="ltr">
        <div>Hi Archie!</div>
        <br>
        <div class="gmail_quote gmail_quote_container">
          <div dir="ltr" class="gmail_attr">On Tue, Apr 29, 2025 at
            4:17 PM Archie Cobbs <<a href="mailto:archie.cobbs@gmail.com" moz-do-not-send="true" class="moz-txt-link-freetext">archie.cobbs@gmail.com</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div dir="ltr">
              <div>This reminds me of a bug I saw once decades ago: the
                JVM was not setting the close-on-exec flag on new file
                descriptors, so child processes were receiving copies of
                "leaked" file descriptors and keeping them open
                indefinitely, causing the system to eventually running
                out of file descriptors and crash.</div>
              <div><br>
              </div>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>I remember. We fixed that in jspawnhelper.</div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div dir="ltr">
              <div>The moral of that story was that control of the
                "process environment" of a new process (i.e., which file
                descriptors are open, signal handlers installed, etc.)
                created via the usual fork/exec sequence clearly belongs
                to the bit of code that is spawning that process for
                whatever reason: any inheritable part of the process
                environment that the JVM might mess around with must be
                reset before spawning child processes.</div>
              <div><br>
              </div>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Agreed.</div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div dir="ltr">
              <div>So if some native code wants to configure SIGPIPE for
                SIG_IGN and then fork/exec a child process that inherits
                that setting, then fine.</div>
              <div><br>
              </div>
              <div>But if the JVM itself is doing its fork/exec for some
                unrelated purpose (e.g., Runtime.exec()), it has the
                right and responsibility to clean up the environment
                that the child process is going to inherit to protect it
                from any changes due to the JVM process, including
                native code.</div>
              <div><br>
              </div>
              <div>So it seems like there are two possible bugs here:</div>
              <div><br>
              </div>
              <div>1. Some JNI code links in a library that changes the
                (global) setting for SIGPIPE. Is that allowed by the JNI
                specification? Does the specification even say? It seems
                like this is not really kosher, but anyway it happens to
                work by coincidence because SIG_IGN and
                javaSignalHandler do the same thing (i.e., discard the
                signal).</div>
              <div><br>
              </div>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>To my knowledge the JNI spec says nothing about signals.</div>
          <div><br>
          </div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div dir="ltr">
              <div>2. The JVM is not completely scrubbing the child's
                process environment when it spawns a new process as it
                should: All signal handlers should be reset to their
                default values (unless there is some JVM-specific reason
                to set them differently).</div>
              <div><br>
              </div>
              <div>It seems like #2 is a valid bug or at least a valid
                improvement, and whether #1 is a bug depends on what you
                believe JNI libraries are officially allowed to do.</div>
              <div><br>
              </div>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>I agree. Note that we also have a slight inconsistency
            depending on the order of third-party signal handler
            installation:</div>
          <div><br>
          </div>
          <div>1) In a scenario like the one I described we start java,
            it installs the SIGPIPE handler, which then gets preplaced
            by the third-party lib with SIG_IGN, resulting in child
            processes running with SIG_IGN for SIGPIPE.</div>
          <div>2) If, however,r the libjvm.so gets embedded into a
            custom launcher, which already had set SIG_IGN for SIGPIPE,
            the JVM will replace that handler with its own, resulting in
            child processes running with SIG_DFL.</div>
          <div><br>
          </div>
          <div>This seems a bit arbitrary to me and seems to support the
            view that this behavior is not intended.</div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div dir="ltr">
              <div>-Archie</div>
            </div>
            <br>
            <div class="gmail_quote">
              <div dir="ltr" class="gmail_attr">On Tue, Apr 29, 2025 at
                4:05 AM Thomas Stüfe <<a href="mailto:thomas.stuefe@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">thomas.stuefe@gmail.com</a>>
                wrote:<br>
              </div>
              <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                <div dir="ltr">
                  <div>Hi,</div>
                  <div><br>
                  </div>
                  <div>I would like to gauge opinions on whether the
                    following scenario is a bug to fix or whether to
                    accept it as standard behavior.</div>
                  <div><br>
                  </div>
                  <div>---</div>
                  <div><br>
                  </div>
                  <div>A customer has the following problem:</div>
                  <div><br>
                  </div>
                  <div>- The JVM invokes a third-party JNI library that
                    sets the signal disposition of SIGPIPE to SIG_IGN
                    (Boo! in this case, it is the FIPS nspr library,
                    which does this unconditionally.)</div>
                  <div>- The JVM then spawns child processes</div>
                  <div>- All child processes now ignore SIGPIPE, which
                    leads to failures in automation scripts</div>
                  <div><br>
                  </div>
                  <div>I was surprised. I always assumed the signal
                    disposition of all signals would be reset to SIG_DFL
                    when exec'ing. However, seems I was wrong when it
                    came to SIG_IGN. Posix documents for execve() states
                    [1]:</div>
                  <div>
                    <p>1) " Signals set to the default action (SIG_DFL)
                      in the calling process image shall be set to the
                      default action in the new process
                      image."</p>
                    <p>and</p>
                    <p>2) "Except for SIGCHLD, signals set to be ignored
                      (SIG_IGN) by the calling process image shall be
                      set to be ignored by the new
                      process image." <br>
                    </p>
                    <p>and</p>
                    <p>3) "Signals set to be caught by the calling
                      process image shall be set to the default action
                      in the new process image
                      (see <a href="https://urldefense.com/v3/__https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html__;!!ACWV5N9M2RV99hQ!JGJYVEFhN3cSMzW41RLH_PK_mMddc3HnFEtCKYUXztE2-_9cjl_tIkMLO3y5_vav3Pt2ARimbCm44kuH8n_No6q2$" target="_blank" moz-do-not-send="true"><i><signal.h></i></a>)."</p>
                    <p>(2) and (3) are the interesting parts. (2) means
                      that if the parent process ignores SIGPIPE, child
                      processes will also ignore SIGPIPE. (3) means that
                      if the parent process has a custom handler
                      installed for SIGPIPE, child processes will be
                      started with SIG_DFL (default action) for SIGPIPE.
                      The default action for SIGPIPE is "terminate
                      process".</p>
                  </div>
                  <div>The libjvm handles SIGPIPE. We install our
                    `javaSignalHandler`. We do this to eat up and ignore
                    SIGPIPE. That we "manually" ignore the signal beside
                    the point here - what counts is that we set a custom
                    signal handler for SIGPIPE. Therefore, on execve, we
                    behave according to rule (3) and start the child
                    with SIG_DFL as SIGPIPE disposition. As it should
                    be.</div>
                  <div><br>
                  </div>
                  <div>If third-party code sets the handler to SIG_IGN
                    as in this example, exeve will behave according to
                    rule (2) and the child will start with SIG_IGN as
                    SIGPIPE disposition.</div>
                  <div><br>
                  </div>
                  <div>The libjig can be used to workaround this
                    scenario, but I wonder if that is more of an
                    accident. The libjsig.so will preserve the JVM's
                    SIGPIPE handler even if third-party code attempts to
                    set it to SIG_IGN. That means that exeve still
                    behaves according to rule (2): sets child's SIGPIPE
                    disposition to SIG_DFL.</div>
                  <div><br>
                  </div>
                  <div>----</div>
                  <div><br>
                  </div>
                  <div>But I wonder whether this should not be
                    considered a bug to fix regardless of the jsig.so
                    workaround? In jspawnhelper, we clean the
                    environment from various effects when exec'ing;
                    among other things, we reset the signal block mask
                    for the process. The "ignore" state of processes
                    could be considered along the same line. We could
                    reset all signal handlers to SIG_DFL before execing
                    the child.</div>
                  <div><br>
                  </div>
                  <div>I know that this area is super-tricky and
                    problems are notoriously difficult to analyze; we
                    should therefore be extremely careful not to break
                    downward compatibility. Still, what do people think?
                    Should be fix this in jspawnhelper?</div>
                  <div><br>
                  </div>
                  <div>Thanks, Thomas</div>
                  <div><br>
                  </div>
                  <div>(cc'ing Roger)</div>
                  <div><br>
                  </div>
                  <div>[1] <a href="https://urldefense.com/v3/__https://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html__;!!ACWV5N9M2RV99hQ!JGJYVEFhN3cSMzW41RLH_PK_mMddc3HnFEtCKYUXztE2-_9cjl_tIkMLO3y5_vav3Pt2ARimbCm44kuH8vLbF0yj$" target="_blank" moz-do-not-send="true">https://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html</a></div>
                </div>
              </blockquote>
            </div>
            <div><br clear="all">
            </div>
            <br>
            <span class="gmail_signature_prefix">-- </span><br>
            <div dir="ltr" class="gmail_signature">Archie L. Cobbs<br>
            </div>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>