[Interest] Roland Qml
Roland Hughes
roland at logikalsolutions.com
Wed Jul 15 16:04:00 CEST 2020
On 7/15/20 5:00 AM, interest-request at qt-project.org wrote:
> I haven't followed the entirety of this thread (as it's split into a few
> different threads for some reason).
That reason would probably be because I get this in digest form and
don't always remember to change the subject line when responding in
Thunderbird. My apologies there.
> I can understand some disdain against the "dumbing-down" of programming
> nowadays and I'm personally not fond of QML (in it's current state) either.
> But you suddenly jump from "JavaScript is insecure" to "medical devices
> running JavaScript will kill patients". Making mistakes can happen in
> every language, and I'm sure quite a few people have died because of
> technical issues in c++ code as well. JavaScript might be more error
> prone -- of course -- but I wouldn't really blame QML for that. If you
> use JavaScript in QML for anything other than visual logic, without any
> validation, unit tests, fuzzing, QA, etc. then you're a bad coder.
As another has pointed out, this wasn't a jump, just a perfunctory
functional safety check. One of the things one does when working in an
FDA regulated or functional safety environment. You open the binary in a
standard text editor making certain nothing is obviously exposed. It's a
practice which evolved/occurs because at some point in history compiled
languages used to put some portions of the program in the binary in
"free text." With nothing more than a decent text editor in overstrike
mode someone with no real skills could change the "free text" and thus
put a life at risk. Traditionally this happened with hard coded strings.
While many could/would view that as "pranking" because someone could
tweak the help text in a funny way, it's life threatening if one has
maximum dose strings or tables and someone changes "Milligram" to
"Gram " or some such unit change. Yes, if it exists in text it is
usually an abbreviation, but the reality is the same. When the maximum
safe does is 9 Milligrams but now all of the validation logic believes
it to be 9 Grams, a fatality can, and probably will, occur.
The team attempted to use JavaScript for everything because that is what
they knew. We weren't assigned developers comfortable with C++. By and
large this "could" have been okay with sufficient testing as you state.
It certainly wouldn't be efficient on a tiny battery powered device that
had to run everything from one battery, but it "could" have been okay.
When I opened the binary, there was the JavaScript code. In the binary
that would be installed. You could easily change it in overstrike mode
without changing the size of the binary. This is insecure. It's also one
of the biggest fears when it comes to functional safety. Under most
operating systems you can change a file timestamp back to what it was,
at least that has been my experience. Most embedded systems don't add
safety code to image loaders that verify a hidden checksum before
loading and executing a binary. Even when they do many keep all of the
checksums in a single directory or file that can also be changed.
Why this is of such concern is that many people can die long before this
is found. There is lots of regulatory testing on file to prove the
device cannot have failed in the suspected manner. If someone manages to
park said new binary at a field service site, it can distribute wide as
part of routine maintenance. Yes, there is lots of security that is
supposed to prevent such things but the operative word is "supposed".
Security can be breached with enough time and intent. You are supposed
to not make it easy for them to hurt you once they are in.
Yes, someone "could" be good with a disassembler as in this conversation.
https://stackoverflow.com/questions/5125896/how-to-disassemble-a-binary-executable-in-linux-to-get-the-assembly-code
but now you are at a level that is above easy. Compared to tweaking
multi-threaded C++ program that has been disassembled tweaking
JavaScript is easy. Tweaking the former requires someone with quite a
bit of skill and/or training who practiced a lot. Change the distance of
a single branch and everything can crash, or at least it could in the
x86 days which had near and far branches.
http://spot.pcc.edu/~wlara/asmx86/asmx86_manual_6.pdf
I have no doubt you are correct about their being many many programmers
better than I. My golden era was from about 22 to just shy of 35. There
wasn't a system of any size (and I worked on some really big ones) that
I couldn't put in my head, design, and deliver. I subscribed to and
religiously read Rex Jaeschke's blue standards booklet/magazine
http://rexjaeschke.com/
as well as the "Programmers Journal," "The C Gazzette," and "The C/C++
User's Journal." I lived, breathed, and thought in code. BASIC, FORTRAN,
COBOL, DIBOL, C/C++, it didn't matter, I did it all. I even wrote far
too much Cognos PowerHouse.
Those days are in the rear view mirror. For the past two decades I've
focused on architect level work just doing a bit of coding ( < 10,000
lines per day, usually closer to 5,000) because functional safety and
good design requires way more than coding skills. It requires living,
breathing, and thinking each and every day about the way things go
wrong, not the fastest way to "get it done."
Rolling JavaScript into a binary that can be clearly viewed in a regular
text editor is a massive security risk. It happened because the team
used QML and JavaScript instead of C++. Quality of code didn't matter,
it was the quality of the solution.
At a minimum, the JavaScript should have been UUENCODEd into a blob
within the binary then UUDECODEd at program load. This would make it far
less easy for one to mess with it if they wanted. I cannot eliminate
said want, but I can eliminate the ease with which one can fulfill said
want. Any encoding really, I just grabbed UU out of the air because it
is widely available and old. Here is a file from notepadqq.
=====
roland at roland-HP-EliteDesk-800-G2-SFF:~/jnk5$ cat toEnd.js
var common = require('./common');
var fs = require('fs');
var path = require('path');
//@
//@ ### 'string'.toEnd(file)
//@
//@ Examples:
//@
//@ ```javascript
//@ cat('input.txt').toEnd('output.txt');
//@ ```
//@
//@ Analogous to the redirect-and-append operator `>>` in Unix, but
works with JavaScript strings (such as
//@ those returned by `cat`, `grep`, etc).
function _toEnd(options, file) {
if (!file)
common.error('wrong arguments');
if (!fs.existsSync( path.dirname(file) ))
common.error('no such file or directory: ' + path.dirname(file));
try {
fs.appendFileSync(file, this.toString(), 'utf8');
} catch(e) {
common.error('could not append to file (code '+e.code+'): '+file,
true);
}
}
module.exports = _toEnd;
=====
roland at roland-HP-EliteDesk-800-G2-SFF:~/jnk5$ uuencode -m toEnd.js a.out
begin-base64 644 a.out
dmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7CnZhciBmcyA9IHJl
cXVpcmUoJ2ZzJyk7CnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpOwoKLy9A
Ci8vQCAjIyMgJ3N0cmluZycudG9FbmQoZmlsZSkKLy9ACi8vQCBFeGFtcGxl
czoKLy9ACi8vQCBgYGBqYXZhc2NyaXB0Ci8vQCBjYXQoJ2lucHV0LnR4dCcp
LnRvRW5kKCdvdXRwdXQudHh0Jyk7Ci8vQCBgYGAKLy9ACi8vQCBBbmFsb2dv
dXMgdG8gdGhlIHJlZGlyZWN0LWFuZC1hcHBlbmQgb3BlcmF0b3IgYD4+YCBp
biBVbml4LCBidXQgd29ya3Mgd2l0aCBKYXZhU2NyaXB0IHN0cmluZ3MgKHN1
Y2ggYXMKLy9AIHRob3NlIHJldHVybmVkIGJ5IGBjYXRgLCBgZ3JlcGAsIGV0
YykuCmZ1bmN0aW9uIF90b0VuZChvcHRpb25zLCBmaWxlKSB7CiAgaWYgKCFm
aWxlKQogICAgY29tbW9uLmVycm9yKCd3cm9uZyBhcmd1bWVudHMnKTsKCiAg
aWYgKCFmcy5leGlzdHNTeW5jKCBwYXRoLmRpcm5hbWUoZmlsZSkgKSkKICAg
ICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAn
ICsgcGF0aC5kaXJuYW1lKGZpbGUpKTsKCiAgdHJ5IHsKICAgIGZzLmFwcGVu
ZEZpbGVTeW5jKGZpbGUsIHRoaXMudG9TdHJpbmcoKSwgJ3V0ZjgnKTsKICB9
IGNhdGNoKGUpIHsKICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IGFwcGVu
ZCB0byBmaWxlIChjb2RlICcrZS5jb2RlKycpOiAnK2ZpbGUsIHRydWUpOwog
IH0KfQptb2R1bGUuZXhwb3J0cyA9IF90b0VuZDsK
====
I think we can all agree it is much more difficult to "tweak" that.
One can even compress the blob if they want to make the binary tighter.
roland at roland-HP-EliteDesk-800-G2-SFF:~/jnk5$ uuencode -m toEnd.js a.out
> t.out
roland at roland-HP-EliteDesk-800-G2-SFF:~/jnk5$ ls
toEnd.js t.out xpnsqt3
roland at roland-HP-EliteDesk-800-G2-SFF:~/jnk5$ zip t.zip t.out
adding: t.out (deflated 36%)
roland at roland-HP-EliteDesk-800-G2-SFF:~/jnk5$ ls
toEnd.js t.out t.zip xpnsqt3
roland at roland-HP-EliteDesk-800-G2-SFF:~/jnk5$ ls -al
total 6436
drwxrwxr-x 2 roland roland 4096 Jul 15 09:00 .
drwxr-xr-x 195 roland roland 20480 Jul 15 08:45 ..
-rw-r--r-- 1 roland roland 750 Jul 15 08:45 toEnd.js
-rw-rw-r-- 1 roland roland 1045 Jul 15 09:00 t.out
-rw-rw-r-- 1 roland roland 827 Jul 15 09:00 t.zip
-rwxrwxr-x 1 roland roland 6552984 Jul 15 08:49 xpnsqt3
Yes, I'm sure there are many non-U.S. programmers who are dramatically
better coders than myself who would be a benefit to any project they
joined. Corporations, at least in America, don't go off-shore to find
good skills, they go off-shore to find "priced right." The pond they are
fishing in doesn't have any of the highly skilled people because they
can earn way more. Doesn't matter what country you are in, when the
company you work for goes shopping for "priced right" you don't get the
cream of the crop.
--
Roland Hughes, President
Logikal Solutions
(630)-205-1593
http://www.theminimumyouneedtoknow.com
http://www.infiniteexposure.net
http://www.johnsmith-book.com
http://www.logikalblog.com
http://www.interestingauthors.com/blog
More information about the Interest
mailing list