Comment by phoe-krk
3 years ago
So that function checked if the following C code compiled, and only in that situation enabled the landlock?
Except that lone period, hard to recognize because of its small size and proximity to the left edge of the diff, caused the C code to become always invalid, hence keeping the landlock always disabled?
That's both vilely impressive and impressively vile. I didn't even spot it on my first read-through.
It also shows how brittle these sorts of checks are in general. I really think that this auto-disable of features based on compilation was a big mistake. It is not only very annoying when packaging things (Why does feature X not work? Because you forgot to include libY in the build environment of course) but they also fail silently even if intended. While this `.` was almost certainly malicious it is easy to imagine an accidental break. Maybe a minor typo or `-Werror`is enabled any one of these functions was marked as must use or something similar.
It seems like it is infinitely better to have a default set of features and explicitly require the user to say `--enable-x --disable-y` as needed. Then error out if a required library isn't available. (Preferably saying which feature requires it.)
This is what the cargo/rust ecosystem does :)
It's also iffy tbh. that the compilation check functionality:
- doesn't force users to differentiate between syntax errors and other errors (e.g. symbols not found). Partially you can't even make it work properly if you want due to C macros.
- it seems sensible, tbh. if "does compile" checks for compatibility seems sensible then there is so much wrong with the ecosystem in so many ways
It's standard autoconf stuff, BUT... the right thing to do for a security option should be to throw an error at the configure stage If the Option is requested but can't be supported, And not to silently turn it off.
That is because a human should have to Look at the build and manually make the decision to switch off a security feature from the build.
Autocomf output is so incredibly noisy though, still long odds someone would notice anytime soon.
2 replies →
Agreed. I just opened https://gitlab.kitware.com/cmake/cmake/-/issues/25846 although I have no idea how hard it is to address this sort of issue robustly.
Even more evil would have been to replace this line
with this:
For those squinting, the "landlock" regular "c" is replaced with a Cyrillic U+0441.
Yip, this was impressive. Only a copy & paste into VSCode (Windows) revealed the rectangle around the "c" in the second line.
Impressive.
Is there a GCC option to error on non-standard English characters?
19 replies →
Putting random Unicode confusables in source code would be far easier to consider malicious
Except many people have a policy of ASCII only in source code and therefore would catch it immediately.
Another point where I appreciate the Rust compiler:
https://play.rust-lang.org/?version=stable&mode=debug&editio...
The character was in a string, not directly in what was being compiled. The contents of the string failing to compile was the point, as landlock was then disabled.
From what I understand, this landlock disabling wasn't relevant to the sshd attack. It appears it was setting up for something else.
With the . the author can claim it was unintentional. It's impossible (or at least very hard) to claim the Cyrillic c is unintentional.
To me, that makes the . more evil.
Well, on Russian keyboards, they are on the same key.
3 replies →
Plausible deniability
1 reply →
After the concept of such attacks had blow up idk. 1?2?3? years ago a lot of places now warn at least when mixing "languages"/ranges or sometimes on any usage of non us-ascii printable characters.
So stuff like that is increasingly more reliable caught.
Including by 3rd parties doing any ad-hoc scanning.
Through adding `compiles check` fail with syntax errors definitely should be added tot he list of auto scan checks, at least in C/C++ (it's not something you would do in most languages tbh. even in C it seems to be an antipatters).
Nearly every modern IDE and diff viewer instantly highlights this though? I doubt this would get far.
compiler would perhaps "see" it ?
Sure; but so long as the compiler error is silently discarded (as it is here), the configure script will assume landlock isn't available and never use it.
5 replies →
I just got a little more respect for pythonic whitespace-sensitivity
EDIT: come to think of it, even that might not have done much here, where well-formedness is the issue :(
Yeah, if anything, python worsens the situation. I had a friend DOS our server because he accidentally inserted a tab, causing the illusion that one statement was inside a block but was actually outside it. He swore off python at that point. I personally avoid the language, but I understand due to issues like that these days mixing tabs and spaces is an error (or is it just a warning?) by default. Regardless, still pretty silly to me to have whitespace play such a major significant role, besides the fact that I find it visually harder to read, like text without punctuation or capitalisation.
Mixing tabs and spaces usually throws a runtime exception. I'm not gonna make a value judgement about that, but your story doesn't make sense based on how I understand py3
Edit, sorry, shoulda read your whole commebt before replying
16 replies →
white space as a delimiter is why i never use python.
13 replies →
Yes mixing tabs and spaces is a big no no and rightfully throws an error now
1 reply →
humans are weird creatures sometimes. there was this bad thing that happened that won't happen again now, but now I can't use the thing forever because Reasons.
In Python, you only need to indent the `def test_foo` by an additional whitespace, to make it a locally scoped function instead of a proper test function.
No, not if you have any sane linter or formatter involved. They wouldn't let you get away with indenting by a single space, but only by multiples of whatever you normally use in the rest of your program.
3 replies →
AST diffs instead of textual diffs might have helped here (to spot the `.` making the code un-compilable).
Edit: oof, though the stray character in question is inside a perfectly legitimate C string, so to catch this, any such diffs would need to Matroyshka down and that seems unsolvable / intractable.
> Edit: oof, though the stray character in question is inside a perfectly legitimate C string, so to catch this, any such diffs would need to Matroyshka down and that seems unsolvable / intractable.
Not sure, you could also just forbid code that's too complex to analyse without going down a rabbit hole. Instead of trying to go down the rabbit hole.
In general, it's hard to analyse arbitrary code. But we don't have to allow arbitrarily complex code when doing code review.
I think main issue was that it was embedded in the file itself like that. Would have preferred to have it in a separate valid C file with syntax highlighting etc and being parsed from that file.
5 replies →
Ah yes but thanks to C being cursed due to includes and macros this is harder to do
8 replies →
I agree. The way I read this, I missed it completely until I searched for it. I was looking too closely at the rest of the code around defines