What is your complaint? Everything you need to about the
Wow. You have to ask? You don't see anything wrong
with that?!
issue is right here. Perhaps you shouldn't have mounted
Neither I, nor the end user, did any such thing, nor
do we even know what "mount" means. That's not
our job.
the filesystem containing the shared object with the
no-exec flag.
$ mount | grep tmp
Correct. That is the underlying technical issue. They
couldn't have made it more complicated. Well, maybe
they could have. They could have issued a message
saying:
Your application failed when it executed the OS
call located at 0x00ff3299a6 passing 0x23738
in %rax, which is what really got you. But the
parameter at offset 0x52 on the stack was
involved too, just saying.
Yeah, thanks Linus. I was looking forward to
computers in 2021 too.
Ok, now for the write-up.
This is a real-life situation (in 2021). Only the names
of the users have been changed, to protect the innocent.
An end user running an application is expecting to
receive a message of either "all records successfully
processed" or an error along the lines of "line 2000
in your input file contains non-numeric digits in the
phone number associated with Fred Smith". (And they
are totally trained on how to deal with either scenario
above). Instead, they were presented with:
Failed to load native library:sqlite-3.32.3-cfaaf6a4-6366-4cb2-b785-868ad9482e9f-libsqlitejdbc.so. osinfo: Linux/x86_64
java.lang.UnsatisfiedLinkError: /tmp/sqlite-3.32.3-cfaaf6a4-6366-4cb2-b785-868ad9482e9f-libsqlitejdbc.so: /tmp/sqlite-3.32.3-cfaaf6a4-6366-4cb2-b785-868ad9482e9f-libsqlitejdbc.so: failed to map segment from shared object: Operation not permitted
Plus a shitload more Java messages, I think "beans" got
more than one mention, and "utf8" got a mention (the
input files don't contain utf8, but why let that get in the
way of a good error message?).
If I were the end user, my first reaction would be "Holy Cow,
it's Armageddon!" or at least "Holy Cow, Russian hackers
have taken over the computer system!".
Obviously it's beyond their pay grade, but at some level
they know to report the problem to the programmers who
wrote the application rather than the sysadmin. Even if
they get that wrong, the sysadmins can probably spell
"programmer".
So it winds up at the programmer's desk and the process
can begin.
Note that before I disappeared to Tibet, I was working on
IBM mainframes, in the 1980s, and users would be hit
with either an application error message which both they
and the programmer understood, or they would get
something like:
IKJ1234T - virtual memory exceeded
And they could look that "IKJ1234T" up in a manual and it
would say "user response: do xyz, and if problem persists,
see your systems programmer". My largest complaint was
that, as a systems programmer, IBM hadn't also included
"systems programmer response: do abc, and if problem
persists, report it to IBM".
But no worries, I'm sure computer scientists around the
world will have that sorted out by 2021 while I was busy
yodeling in Tibet.
What I wasn't expecting was that with hardware engineers
making truly ridiculous amounts of CPU power, memory and
hard disk space available, we would take a step so far back
in time we may as well be using vacuum tubes.
So as discussed, the problem has made it to the application
programmer. The application is actually in Java, not C, and
if they had received a message "string index of variable
xyz on line 2321 was out of bounds (15)" they would in
fact know what to do.
Instead, they are presented with ancient Swahili.
Failed to load native library:sqlite-3.32.3-cfaaf6a4-6366-4cb2-b785-868ad9482e9f-libsqlitejdbc.so. osinfo: Linux/x86_64
java.lang.UnsatisfiedLinkError: /tmp/sqlite-3.32.3-cfaaf6a4-6366-4cb2-b785-868ad9482e9f-libsqlitejdbc.so: /tmp/sqlite-3.32.3-cfaaf6a4-6366-4cb2-b785-868ad9482e9f-libsqlitejdbc.so: failed to map segment from shared object: Operation not permitted
Assuming you know to look at this bit, which were
the first messages rather than the last or middle,
you can start diagnosing the problem.
Ok, so maybe they know what "native" means. It is
custom-designed for this computer. But what's a
"library"? Never heard of it. Other than a place that
has books. If you have a specific .java file you are
referring to, I can cope with that. But no library, no
books.
I don't know what "cfaa..." is - that's a strange name
to call your so-called "library". Perhaps at some level
we can guess that we should ignore everything written
in hex, and just focus on the Swahili characters.
There is a specific name - sqlite and jdbc. I'm not sure
if Java programmers are actually aware what packages
provide them with database capabilities, but let's say
they do. They recognize that as "ah, the database has
a problem". And let's further suppose that they know
that they are defacto responsible for the database in this
instance, they can't pass the problem on to the DBA.
Ok, so now we have UnsatisfiedLinkError. Maybe the
Java programmers can look this very strange error up
in the Java manual and be informed that we're back
to that "native library" thing. Ok, so we know that a
native library with a very strange name, full of hex, and
in /tmp (not a known application directory) has some
sort of problem. How did this become our problem?
We are not responsible for what crap Linus put in /tmp.
If the OS is apparently putting some strange internal
file into /tmp to do god knows what, that's not on us.
But let's say Linus is in Tibet himself at the moment and
we need to solve the problem ourselves.
If you look hard enough, you will find libsqlitejdbc.so in
the .jar file, so you can maybe guess that there is some
Java code that knows what to do with this .so file. And
indeed, there is, there's a suite of sqlite-jdbc java code.
Still not my problem, except it became my problem when
I started using freeware that doesn't print error messages
like "IKJ1234T". Ok, at that level I can accept responsibility.
I'm now the proud owner of sqlite-jdbc.
failed to map segment from shared object: Operation not permitted
What does "map" mean? What is a "segment" - I know what
a segment register is, but most people don't. "shared object"?
Never heard of it. "Operation not permitted" - why not, is it
against state or federal law, and why didn't you tell me which
one in the first place instead of being coy?
And that's actually the end of the useful diagnostics. You're
supposed to solve the problem with that.
The next logical step would be to look up the word "failed"
in the error message manual, to see what the user response
to "failed to map segment" actually means. IKJ1234T is a
lot more sensible to look up than "failed", but hey, maybe
Linus isn't very good at counting.
Perhaps the underlying problem here is people making their
production processes dependent on what a bunch of
volunteers randomly choose to volunteer instead of going
to an organization like IBM that has people specifically
hired because they know how to count (just as they did
in the mid 1980s and maybe even earlier).
Or if IBM is too expensive, whoever IBM's competitor is.
But again, someone else who knows how to count.
It so happens that with the aid of the internet, I was
eventually able to isolate the root cause as a call
to mmap() (although I don't know who exactly is
doing that, and noting that it is a function that I
was previously unfamiliar with, and noting that it
isn't even Java, and this is a Java application).
And it turns out that at least on our system, you
can't put executables (and "shared libraries" seem
to count here) in /tmp, because it has been deliberately
configured/mounted to prevent such executables from
being run. If Linus thinks that's a good idea, ok, fine, I
don't care. SO LONG AS he prints out a message saying
"hey sucker, you're not allowed to put executables, or
even .so files like you are using, on /tmp, because YOU
SUCK, so go and put it in a different directory".
I don't mind being insulted, so long as you tell me what
your ridiculous rules are. If you're going to impose such
a rule, then also provide some sort of safeguard. Any
application (so this would be sqlite-jdbc) that writes
out executables to a file system and then attempts to
execute them, should have a way of checking that this
file system hasn't been mounted as no-exec and either
find another file system to write to, or ask the user to
provide one by setting an environment variable, in a
very clear message.
Note that this would be very Linux-specific code, not
C90 or Java, but when you do things like create your
own executables (which is basically what is being
done, even if it's just being copied from somewhere
else, and assuming you're not stuffing up permission
bits in that process), you're writing system-specific
code anyway, so it is reasonable to pay the piper. But
it does make it difficult to future-proof your software
if some jackass OS vendor decides to implement a
new new rule that "you can't execute executables
from any directory with "t" in the name". There needs
to be some new standard, similar to C90, that provides
a way of executing executables on all computer systems,
including MVS.
Irrespective of the standard, one way or another, this is
what should have happened.
The end user is presented with a message:
A system error has occurred. Please pass the below
information on to the vendor (programmer) of your
application which is called "fix_phone_numbers".
(reams of indecipherable crap)
The systems administrator is presented via email or
whatever, plus a message in /var/log/syslog, saying:
User fred executed fix_phone_numbers which internally
attempts to put an executable on /tmp, which, as you
know, you personally mounted as no-exec, so it won't
be allowed, but both the user and the programmer are
obviously going to be too stupid to figure that out for
themselves, so please contact fred on mobile phone
number 1234 5678 and tell him that you are going to
speak to the programmer, bob, and ask him what
mechanism, probably an environment variable, allows
the user to specify what directory temporary
EXECUTABLES are written to, because /tmp is
completely inappropriate.
The programmer is presented (as part of that reams of
crap above) with very clear information that a specific
executable file called libjdbc.so was written to /tmp (which
is allowed) and then attempted to be executed (which is
not allowed, because /tmp is mounted (using the "mount"
command or /etc/config) as "no-exec", preventing
execution). The reason /tmp was chosen is because it is
the default if environment variable TEMP_EXEC is not set.
The reason we're writing out an executable in the first
place is because Linux doesn't have the ability to execute
an executable directly from a .jar file which is what we
would ideally want, and hopefully Linus will get off his
fat ass one day and fix that, with Java being the most
popular language in the world and all that, even though
we should have all stuck with C90, for reasons which I
won't get into at the moment. And also Linux doesn't
provide a syscall to find out whether a directory is on
a filesystem that is mounted no-exec, so we can't warn
you about that in advance and not even bother writing
the executable in the first place, although I guess we
could have done our own mmap() to guess in advance
that this was about to go down. Maybe the sqlite-jdbc
people need to get off their fat asses too.
I'm willing to negotiate, both the exact wording, and add
further information you think might be useful in this situation.
Or am I asking for something that is technically
impossible, even in 2021? Do we need to wait
until we have 128-bit long long longs?
What would you do if you had control of an OS and
could create any standard you wanted? We actually
do live in the free world where you can do exactly
that. The folks at ISO aren't going to kick your door
down because you created a non-ISO standard. You
personally have multiple levels of protection against
ISO's goon squad. Specifically, you have men with
guns that can easily defeat ISO's goons. Therefore,
the sky's the limit. All you need to do is negotiate
with Scott, who seems to think that if Linus doesn't
think something is a good idea, then that's the final
word on all matters. Maybe he just doesn't like
upstarts from the southern hemisphere? Linus is yet
another stinking northerner, after all, so he's "cool"?
BFN. Paul.