Mark,
On 11/25/20 22:30, Christopher Schultz wrote:
Mark,
On 11/25/20 12:49, Mark Thomas wrote:
On 25/11/2020 16:46, Christopher Schultz wrote:
<snip/>
Strange that the library is getting a direct reference to the response's
file descriptor. That seems (to me) to be a tactical mistake in an
implementation. Then again, I'm not looking at what is actually being
accomplished, there... it may make perfect sense in context.
The library creates a pipe and so gets two file descriptors. It closes
the file descriptors so they are returned to the OS's pool of file
descriptors. Shortly afterwards the OS reuses one of the file
descriptors and assigns it to the socket. So far, so good. Then the
library closes the file descriptors for a second time and that closes
the socket.
That would do it for most situations, but this is a child process
closing a file descriptor twice. It shouldn't break the parent process,
should it? I mean, if I could write a program that could steal fds from
its parent process, that would be a pretty big security bug.
Or is the issue that this is actually a "thread process" and not a
completely separate process, so they share a fd pool?
The more I think about this the less it makes sense unless I'm missing
something.
I want to go back to your earlier statement:
"
strace shows the .so file being accessed, then we see the process
forking, a pipe set up between the parent and child and the child
calling execve on the same .so file.
"
So this is a typical fork-and-exec to start another process. The child
inherits the fds from the parent. Calling execve means that the child
process is replaced so this isn't a "thread" if it somehow started that
way. (Specifically, this means that we aren't sharing a fd *table*
between processes, even if some fds are actually mapped to the same OS
fd between processes.)
The non-JVM native library is being invoked, and it's decided to
fork-off a process ... of itself? Hmm... that's odd in a JVM
environment, but ... okay, I guess.
"
After a normal clean-up the parent then calls close on the two file
descriptors associated with the pipe for a second time."
So the child cleans them up AND the parent cleans them up? Or the parent
cleans when up twice? The child should be able to call close() as many
times as it wants and only poison itself. Does the child process ever
exit()?
The parent process must be the JVM process, right? And the parent
process (this native library, running within the JVM process)
double-closes file descriptors, with some measurable delay? That's the
only way this could make sense. And of course it mess mess everything up
in really *really* unpredictable ways.
-chris
PS There are some cases where calling close(int) more than one time
actually makes sense, but it's very rare. Evidently, HP-UX requires this
if close() fails in certain ways, while most other systems prohibit
double-calls to close() even when a failure occurs. So much for
portability. Anyway, my guess is that this isn't an HP-UX library ported
to Linux with a logic flaw introduced by that port. It's more likely
just an implementation bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org