the implementation I originally provided does not in fact solve the issue!

the attach protocol initiation "handshake" requires that the "attacher" (the 
caller of this code) and the "attachee"(the target JVM to be "attached" to) 
*must* share a "/tmp" (or access to the attachee's `cwd`)  in common in order 
to rendezvous on the "attach" socket (created in the /tmp or attachee `cwd` 
filesystem).

"attacher" and "attachee" JVM processes are guaranteed to share a common 
directory/filesystem when thy occupy the same "mount namespace", this is the 
environment in which "peers" exist, and the attach
handshake (initiated by the attacher) can use "/tmp" to establish the socket 
connection with the attachee.

with the advent of "containers" (implemented in Linux via various namespaces, 
e.g.: pid & mount) another "attacher" and "attachee" relationship exists, that 
of "attacher" (namespace ancestor) and "attachee" (namespace descendant).

in this environment it is possible (and highly probable) that the "attacher" 
and the "attachee" do not share a directory in common.

In this scenario the "attacher" must resort to handshaking with the attachee 
via the /proc filesystem in order to access the "attachee's" directory from the 
"attacher".

In order to achieve this rendezvous, the "attachee" must occupy a descendant, 
or same, (pid) namespace of, or as, the "attacher".

since (pid) namespaces are hierarchical, a descendant process (in its own 
descendent pid namespace) will also occupy all its ancestor (pid) namespaces 
(between it and the 'root' or 'host' pid namespace) with a unique pid in each 
of those "interstitial" (pid) namespace(s).

thus the "attachee" directory is accessible, via an "ancestor's" (or peer's) 
/proc filesystem using the pid of the "attachee" that is associated with it in 
that (pid) namespace.

thus an "ancestor" "attacher" can handshake with a descendant "attachee" in 
this fashion.

therefore an "attacher" has two choices when attempting to attach:

- use the /proc/<pid>/root/tmp path to the "attachee's" /tmp (or its cwd)
  - this works with both peers and descendants

- use /tmp
  - this only works if the "attacher" and "attachee" share a /tmp in common

the obvious choice is to default to /proc/<pid>/root/tmp (or cwd) however there 
is an issue with this; should the attachee have elevated privileges, the 
attacher may not have r/w permission on the attachee's /proc/<pid>/root (or 
cwd) path.

In these circumstances, the "attacher" can only resort to /tmp which may or may 
not be in common with the "attachee".

the logic required for an "attacher" to determine if an "attachee" /tmp *is* in 
common unfortunately requires read access (from the attacher) to 
the"attachee's" /proc filesystem (namely to read namespace identities and to 
also 'stat(2)' the /proc/<pid>/root/tmp directory to obtain device and inode 
values for comparison in order to determine if "/tmp" is in common.

when the "attachee" has elevated privileges, this access is not available to 
the "attacher".

therefore in such circumstances, the "attacher" has no choice but to attempt
to use /tmp and simply timeout the handshake if in fact the "attachee" does not 
share a /tmp in common

In this elevated case, there is a remote possibility that another process (in 
the attacher's pid ns) shares the same pid as the attachee (in its descendant 
pid ns) in this case, if they do not share a filesystem in common the attacher 
may attempt
to attach to an unsuspecting process in its pid ns, this could result in that 
process being killed.

In order to reduce the possibility of this mis-attach resulting in process 
death, the attacher now tests the attachee to determine if it can participate 
in the attach handshake, by inspecting its signal masks and not delivering the 
signal to
the attachee if it is not catching the signal.

-------------

Commit messages:
 - JDK-8342449: fixed a couple of jcheck issues, modified 
AttachNotSupportedException to indicate that attachee is not ready to accept 
SIGQUIT
 - JDK-8342449: resolve remaing jcheck issues, amend 
AttachNotSupportedException when attachee is not ready to accept SIGQUIT
 - JDK-8342449: cleaned up tabs etc for jcheck
 - JDK-8342449: ignore blocked SIGQUIT in checkCatchesAndSendQuitTo
 - JDK-8342449: suppressed AttachNotSupportedException from 
checkCatchesAndSendQuitTo
 - JDK-8342449: reimplement: JDK-8327114 Attach in Linux may have wrong 
behavior when pid == ns_pid

Changes: https://git.openjdk.org/jdk/pull/21688/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=21688&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8342449
  Stats: 158 lines in 1 file changed: 71 ins; 63 del; 24 mod
  Patch: https://git.openjdk.org/jdk/pull/21688.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/21688/head:pull/21688

PR: https://git.openjdk.org/jdk/pull/21688

Reply via email to