Windows has a new wormable vulnerability, with no patch
arstechnica.com
arstechnica.com
Microsoft hasn't contacted us (Samba) so this almost certainly isn't a protocol level bug (they're very good about being proactive on these), but an error in their implementation of the SMB3 compression transform.
In other words, a typical buffer overrun in a compression library. Gee, wonder where I've seen these before.
Currently Samba doesn't implement the SMB3 transform header, an example where being slow to implement a feature is an advantage for once :-).
So most Linux-based SMB3 servers and NAS boxes (which use Samba) will not be affected by this (I believe - things may change as more information becomes available).
A vulnerability that would transfer between different codebases would be protocol-level because all clients and servers that are to be compliant would have to implement the same protocol(s) and perhaps would easily all write identical state machines. Those kinds of errors are often range errors and logic errors as far as I know, which is a different kind of error as far was I have seen written about this compression bug.
I don't know what compression library Microsoft is using - probably they wrote their own.
It was so nice to have the compiler catch several stupid errors for me. If I were King of the world I would decree that all new public facing software with real world consequences had to be written in Rust. I'm pretty sure I read that Microsoft is looking at Rust to mitigate some of these issues.
Edit: added "new" to make it clear I don't mean rewriting everything in Rust.
Microsoft already tried to migrate bits of userspace to C# in 2008 with windows vista, and that didn't exactly go well...
They also tried to migrate UI stuff to HTML in 1998 (Windows explorer, Active desktop). Didn't work out great either.
Perhaps 10 years is their corporate memory-span and we're overdue another try tho?
When you have legacy code, with millions line of code you just don't swap for something else for the sake of it might be better.
Adding a new language in a medium / large company is not an easy task.
I think Rust is a good contender for C++ "replacement" on the long term but it's a really difficult task and you need proper planning.
There are a billion Windows computers on the planet. Each time we have a buffer overrun which gives attackers access or lets them exfiltrate user data, real people are at risk. At risk of ID theft, of money theft, of scammers, of crypolockers, of extortion and blackmail, of company collapse and job loss, of stolen business secrets, of fines, and of wasted time. Each time we have an urgent patch, tens of thousands of IT people around the world have to hurry to patch/bodge/remediate/mitigate/educate systems with little warning and little testing, dragged away from whatever else they were doing.
Microsoft have proven they can't do this competently in C++. Are we not long past the "might be better to have tools which check" speculation, and far into "definitely definitely definitely is better" by now?
If not by now, what will it take to convince you?
(I'm not saying "Definitely Rust", but something - Microsoft make implementations of C++, T-SQL, C#, F#, JS/TypeScript, VB.Net, and employ many top Haskell people at Microsoft Research, and various other languages, they aren't inexperienced at languages).
it's a really difficult task and you need proper planning.
Then they should hire good developers and plan properly? They are one of the richest companies on the planet who make some of the most popular programming languages and tools on the planet. They're not a poor-me charity case.
https://msrc-blog.microsoft.com/2019/07/18/we-need-a-safer-s...
https://msrc-blog.microsoft.com/2019/11/07/using-rust-in-win...
If you think that's possible why no-one is actually doing it?
The reason that more things aren't yet written in Rust is because these things take time, and there is lots of inertia to switching languages for established projects (one big roadblock to such rewrites is that maintainers need to be familiar enough with Rust).
What "various tools"? Buffer overruns were old-hat decades ago. Impossible in Pascal in 1970, impossible in ALGOL-60 years before that. If the C/C++ tools to protect against buffer overruns in 2020 are worse than the technology of sixty years ago, how much longer do you suggest we wait?
> Because one issue
This isn't the first buffer overrun issue. This isn't the first buffer overrun issue in 2020. PHP has had a buffer overflow which could leak data or crash. IBM DB2 has had a buffer overflow which could allow an attacker to gain privileges. macOS and all iPad/WatchOS and iTunes for Windows have had buffer overruns leading to arbitrary code execution. Samsung Galaxy S10 has. QEMU has. pppd has. SQUID has. CA Nimsoft has arbitrary code execution buffer overflow. PHP Multibyte string handling has. Emerson OpenEnterprise SCADA, libmysofa, OpenJPG, mRuby, libMing, Cisco Unified Contact Center, Honor smartphones, QEMU iSCSI handling, Intel Graphics Drivers, Adobe Reader arbitrary code execution (Again!)
just look https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=buffer
and that's only the CVE disclosed ones.
> If you think that's possible why no-one is actually doing it?
It's cheaper and more profitable not to bother.
Also see the recent slew of security issues on OpenBSD, which is developed by what many consider some of the most skilled and careful C programmers.
Kinda like how a bug should ideally be fixed by reproducing the issue with a unit test first - the test ensures that particular problem won't come back.
AFAIK that's possible for C - a project can be rewritten in Rust one function at a time - but I acknowledge it may not be possible or practical for C++ or other languages.
Thing is, there's going to be tons of old C in Windows that is perfectly safe. That code doesn't need to be changed - and with this model, it wouldn't be. What needs to be changed is components like SMB which has been the source of a few high profile vulnerabilities before.
Additionally, most Windows code is C++ with Windows specific language extensions (COM, Structured Exception Handling, and others).
I think most C++ code should be rewritten in Rust library by library, but most software is not properly constructed as a series of libraries. And asking a business to rewrite working code in a brand new language instead of fixing a buffer overflow is a difficult ask.
https://twitter.com/ryan_levick/status/1225837057186000896?s...
and are doing other experiences as well,
https://www.infoq.com/news/2019/11/microsoft-exploring-rust-...
https://msrc-blog.microsoft.com/2019/11/07/using-rust-in-win...
Kenny Kerr, the original author of C++/Winrt, which replaced C++/CX, has now turned into Rust.
https://kennykerr.ca/2020/02/22/rust-winrt-coming-soon/
They are also motivated to actually make C safer, with Checked C project, something that ISO C doesn't seem to care that much.
https://www.microsoft.com/en-us/research/project/checked-c/
As per MSRC advisory, new code should be a mix of .NET, Rust or Core Guidelines compliant C++, depending on the use case.
Not really, it means that if there is a memory safety bug it must be either in an unsafe block or foreign C code (which also must be called in an unsafe block). While technically any C code could completely invalidate Rust's memory model, in practice that is almost always a C bug which you can debug more easily if much less of your codebase is in C (or equivalently, unsafe Rust).
> Having a codebase which is half C and half Rust sounds worse to read and reason about than all either.
I think that really depends how it's structured. You would probably want to avoid something like Rust calling C calling Rust calling C (calling Rust calling ... etc), but if the codebase is already separated into modules or even separate libraries you could rewrite a library or module while maintaining the same C API (and that Rust or C module can be read independently from the rest of the codebase).
That way functions written in both languages can be mixed.
If there was an actual support from WinDev they would have managed to pull it off, instead they sabotaged the effort and went on redoing those C# classes as COM objects in Vista until we got UWP instead.
These kind of reboots do require a change of developer's generation to pull it off.
C# in 2008 was too early. It was still slow and resource hungry since .NET wasn't that optimized, but also PCs were a lot slower. They sold Vista machines with 1GB of RAM back then. half of that was eaten by the system without opening any actual program you wanted to use.
Using rust shouldn't significantly increase resource usage, and nobody is suggesting you go ahead and design yet another UI framework for it. I'm still perfectly fine with win32 apps today.
Instead they made sure COM would save the day.
What do you know, Microsoft really did embrace Linux, including its design mentality.
FWIW, as a JS/Python programmer I didn't run into borrow checker issues on my most recent Rust foray -- I think it's gotten easier over time with stuff like non-lexical lifetimes?
What I did run into was differences in error handling. If you're used to exceptions it takes a while to get a feel for the variety of idioms that replace them, particularly the chains of and_then().unwrap_or().map().filter().ok().filter_map() that are more familiar for folks coming from pure functional languages.
Coming from JS, this felt familiar to me too: It's virtually identical to how handling errors in Promise chains works.
It also varies hugely according to what kind of program you're writing. Some programs naturally have borrowcheck-friendly structures, others don't.
For example, i wrote a program which processes network packets. There is a main loop which reads packets, then passes them down a pipeline of filtering, extraction, and other processing, eventually sending out more network packets. From the compiler's point of view, the pipeline is just a series of nested function calls. Each call can safely borrow from any of the enclosing scopes. Some of the stages are stateful, but they manage their own state, copying data to and from the packets. There's nowhere in a program like this that you run into a problem with borrowing, it all just flows naturally.
Not really, a lot of things are taken from sensible theory (e.g. traits and typeclasses).
Don't fall into the trap of thinking the entire world is like what you can see from where you're standing. It's not really "not-invented-here", it's "not-invented-there", where "there" is wherever you're used to being. There aren't many unprecedented ideas in Rust.
Beyond that I can't help but feeling that you're following this (IMO) counterproductive cargo cult that holds that sigils are teh 3v1l and everything should be alphanumeric only. Python was at the forefront of this movement but it's now very popular. IMO it's completely counterproductive, even in Python case. It's form over function. You end up with a language where you have to be careful when you refactor because indentation becomes significant and no way to scope your variables properly. Or a language like JS where somebody genuinely thought that having arcane rules to automatically insert semicolons was a reasonable idea because "ewwww semicolons look ugly". It sure looks good if you want to get them tatooed, but in practice at best it's pointless and at worst it gets in the way.
I'm all for descriptive variable and function names but the core syntax of the language is repeated all over the place all the time and benefits from concision. Having Rust spell out "function" instead of "fn" wouldn't disambiguate anything since you're exposed to it within 5 minutes in the language and you'll be super familiar with it very quickly. Having a shorthand means that it doesn't pollute the code listing and leaves more room for the actually important stuff.
A lot of people like to point out Perl as an example of "sigil soup gone wrong" but I'd argue that it's not even the real problem here, Perl can become an unreadable mess because of all the "magic" it allows, meaning you can write code that seems to do absolutely nothing but actually does a whole lot (with things like the implied variable $_ for instance). If you look at an exhaustive list of Perl operators there are only a handful I'd personally consider questionable (like `x` and maybe `<=>`. Also some of the quoting q{} qq{} and qx{} are really obtuse).
It's a joy to write rust code for the most part.
I'll respond to that because there is a concrete benefit. For what it's worth, typescript, go, SML, haskell, and many other languages follow this pattern too.
In C, there's the "clockwise spiral rule"[0] to read a complex c declaration. Let's take an example from that:
void (*signal(int, void (*fp)(int)))(int);
In rust, that would be: fn signal(i: isize, fp: Fn(isize) -> ()) -> Fn(isize) -> ()
In rust, the clockwise spiral rule is more simply the "read left to right" rule, which follows more naturally for most people.For what it's worth, C++ also includes alternate function syntax [1], which matches rust's ordering of return values.
The reason it was added to C++ is because there were actual expressions the old syntax could not unambiguously express. Even to a machine the C-style declaration is more confusing.
With no offence meant, you're sounding a little blub[2]-ish in that complaint.
[0]: http://c-faq.com/decl/spiral.anderson.html
[1]: https://en.wikipedia.org/wiki/C++11#Alternative_function_syn...
What he did was essentially he discovered precedence rules for normal C expressions. That's all. https://news.ycombinator.com/item?id=22451431
And that point is pretty much a straw man, intentionally cherry-picked and obfuscated. The type signature in my signal(3) manpage is given as
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
And functions taking and returning function pointers are exceedingly rare. In practice I still find C type syntax the easiest to read (it's so concise, and in fact there is almost no type synax because it's just expressions). The valid argument for me why we should move away from that syntax is tooling - the syntax is hard to parse for machines (but not for humans) because it requires serial reading and complete preprocessing from the start of the file.Actually, the C, C++, Java, C# dynasty being the USA of programming languages seems quite fitting in terms of economics.
Yeah as you've alluded to Rust _feels_ harder, but is easier if one considers the entire effort curve of a project. Rust front loads the problem solving so the hard work is at the beginning of the project instead of C/C++ with its long tail of debugging that takes up 90% of one's effort.
Of course, if you don't know that the hard work at the beginning is going to pay off it's hard to commit to it. And coders don't know that until they've tried it. It's why I think Go is a good stepping stone to Rust.
Go is easier to get into and useful in its own right, but most importantly it introduces the concept of "if it compiles, it runs" to coders who are used to compilers that fight against them (ala C/C++, Java, Python, JavaScript, etc). Once someone has a taste for helpful compilers I think it's easier for them to swallow Rust. In particular that idea that the borrow checker is there to _help_ you and the supposed "difficulty" of working with it is more about the compiler being transparent with you, instead of the C/C++ way of looking at your broken program and just shrugging and going "Okay, if you say so...".
Indeed, and I think this principle applies to other things, like statically-checked type systems. You have to decide types early, but it means a huge class of bugs becomes a non-issue.
I love Rust, but that is nonsense. First of all it's a reasonable complicated language even without lifetimes and the borrow checker, but let's ignore that. My issue with this sentiment is that it ignores the fact that the borrow checker isn't smart enough to prove that loads of perfectly valid programs are valid.
A simple example: `a[0].foo = a[1].foo;`. Perfectly valid. No memory errors. But Rust isn't smart enough to know, and so it really does make things harder than in C/C++.
This isn't a criticism of Rust at all. I think it is a worthwhile tradeoff to get memory safety. I just wish people would stop pretending that it isn't a tradeoff at all!
Also, if foo is a non-shared pointer that copy doesn't seem safe.
Depends on exactly what you mean; if you're trying to say, replace one part of an array with another, you would use copy_from_slice https://play.rust-lang.org/?version=stable&mode=debug&editio... (or clone_from_slice if your struct isn't Copy)
Also, your parent is just plain incorrect, Rust does let you do that https://play.rust-lang.org/?version=stable&mode=debug&editio...
fn assign(a: &mut Bar, b: &Bar) {
a.foo = b.foo;
}
assign(&mut a[0], &a[1]);
Bit contrived - next time Rust stops me doing something simple I will note it down!Again to be clear, I'm not saying that there's anything wrong with Rust here.
Unfortunately, Active Directory Domain Controllers must expose it to function properly, so hitting those machines with the workaround registry value is a good idea.
Is that something that ever happens on purpose?
https://docs.microsoft.com/en-us/azure/storage/files/storage...
time to shill ATS
It's probably a lot lower than the cost of never implementing the software in the first place.
https://msrc-blog.microsoft.com/2019/07/16/a-proactive-appro...
70% exploits leading to a few billions in salaries to everyone involved fixing those holes.
Buffer overflows don't even show up in OWASP's list of top 10 vulnerabilities, most of which are language agnostic.
Aside from that, a tally of the cost of buffer overflows is dwarfed by a tally of the cost of CPU cycles, RAM, and other system resources wasted by the inefficiency of safe languages and their ecosystems.
That would mean ruling out a whole lot of performance-critical software (including that written in unsafe Rust). Be careful what you wish for.
Doesn't matter what kinds of checks you put in. It might matter what kind of runtime you have, but a runtime isn't a language, is it? We're talking about the language, and any language sufficiently expressive to allow you to say "loop until you are done" instead of "loop precisely 20 times" is inherently unsafe.
Guess what, their system language ESPOL, an Algol derivative later replaced by NEWP, already had unsafe code blocks.
Binaries that made use of unsafe were tainted and required that the admin would given them permission to execute.
This almost 10 years before C was created.