NSA urges orgs to use memory-safe programming languages
theregister.com
theregister.com
NSA guidance on how to protect against software memory safety issues [pdf] - https://news.ycombinator.com/item?id=33553668 - Nov 2022 (90 comments)
https://www.chromium.org/Home/chromium-security/memory-safet...
>The Chromium project finds that around 70% of our serious security bugs are memory safety problems. Our next major project is to prevent such bugs at source.
https://msrc-blog.microsoft.com/2019/07/22/why-rust-for-safe...
>As we’ve seen, roughly 70% of the security issues that the MSRC assigns a CVE to are memory safety issues. This means that if that software had been written in Rust, 70% of these security issues would most likely have been eliminated. And we’re not the only company to have reported such findings.
Even HN still has a fair number of comments along the lines of “C++ is fine, you just need to do things the modern way and avoid making any mistakes”...
Everyone else who has ever contributed to your codebase. "Just use modern C++" is a good way to tell who has never worked on anything but the greenest of greenfield projects.
> “C++ is fine, you just need to do things the modern way and avoid making any mistakes”
I know I will be burned now, but: Which is kind of true if you stick to modern C++ (>11) .. and if you do that (maybe enforced by a style checker or some new cpp standard setting?) you even strip out the "avoid making any mistakes". Again, fully admitted, C++ is kind of a grown and ugly language, with many holes that you could use if you don't systemically forbid them.. but if it just would make real step to enforce / deprecate with a safe-strict-standard all the bad old C/C++ heritage and there'd be something like an enforced safe-C++, I think it would not be too far away from Rust..
.. because I lately read a Rust paper "Safe Systems Programming in Rust" and what did I needed to read there?: "There are a number of data types whose implementations fundamentally depend on shared mutable state and thus cannot be type-checked according to Rust’s strict ownership discipline. To support such data types, Rust embraces the judicious use of unsafe code encapsulated within safe APIs." (and more schizophrene explanations how we still can do everything in Rust, but are safe follow..)
If that is the case, then this is really not too far away from safe&modern-C++, where you only touch the unsafe parts for hard to find last bits of performance?
Especially, and hear me out .. what I'm not getting is consider the typcal embedded/automotive and similar applications, which usually run single threaded and without any dynamic memory allocation and by that already exclude all of the data-race and other problems. You are basically left with bounds-checking on arrays and similar buffers, and you can really, no you will have that if you use modern C++?
I'm really confused more than ever :) .. but the rust complexity curve does not seem to be only high for the devs, but also for the orgs who require standardization&certification. Hope that will follow now, and also some way to completely abandon unsafeness completely in Rust before we put it so high up the throne? and plea
Haven't we seen any Rust security issues because there is so little software out with it? If some memory unsafeness in some Rust program happens, will we always hear then Rust is safe, this was just unsafe code (like today it was all every time the hacker's fault?? :D )
I guess technically if you forced all allocations to be in unique_ptr<> and then used std::move every time you passed it as a parameter, you would kind have the first part of rust (ownership rules) down.
But the borrow checker? Not sure how that’s possible. It might be (and in fairness, you could require all references to be const)
But I am not sure if there’s a way to do the usual 1 and only 1 borrowed mutable value. (Unless someone can think of a way?)
There are some who develop in both C and C++, along with any other language you can think of. I do not encounter the expression "C++/Rust dev", although it is extremely common for those programmers who do Rust at all to do both.
What you are calling C++ is actually C/C++, or as I've recently taken to calling it, C+C++.
It is objective fact that all female former US presidents can fly by flapping their wings.
It may not mean much to you, but to a non technical CEO or board of directors it has meaning.
The advantages of memory safe languages have been discussed to death in programming circles for many decades.
This is absolutely nothing new, and it should surprise absolutely no one that both industry and government are behind the curve, as usual.
5 years ago, there was not broad consensus by technical leaders that C/C++ was even a problem. You just needed the best programmers, throw in some *SAN to rinse all the bugs away and poof!, fast enterprise grade code!
Who delivers a message is often times more important than the message itself. The entire message is (person, says, x), I said we should stop using C/C++ 20+ years ago, doesn't make me CTO of Azure or the NSA.
Those of us using modern C++ do not ship memory usage faults, and have not done for years. So, experience with C and pre-modern C++ does not generalize.
If not, then "modern C++" is still not memory-safe.
The same applies to, e.g., Rust: any Rust program may use unsafe blocks. That Rust programs may contain unsafe blocks does not make Rust implicitly unsafe. Even using unsafe blocks does not, by itself, make the program unsafe.
> Even using unsafe blocks does not, by itself, make the program unsafe.
This is false. "Unsafe" means that there is the potential to cause memory safety bugs. Unsafe blocks and C++ cause this, by definition. "Unsafe" does not mean that a memory safety bug actually exists.
Moreover, I didn't mention anything about Rust in my comment.
If you are coding C or pre-modern C++, then you are not coding modern C++, regardless of the compiler you happen to build with.
Your claim that modern C++ doesn't ship memory safety issues is a fallacy not worth my time for a rebuttal.
Instead, mid-90s C++, with all the leaks, is valid C++, 20 or otherwise.
No true C++20 program is memory unsafe... unless you use a normal pointer, which is always available and will bork you just as hard as in C.
Your argument applies equally well to Rust: any Rust program may include unsafe blocks. That any program may contain unsafe blocks does not make Rust implicitly unsafe. That a Rust program does (transitively) contain unsafe blocks does not make it an unsafe program. All substantial Rust programs at least transitively contain unsafe blocks.
Thus, your argument is invalid.
In some ways Rust is (or will be) particularly well suited to these environments. They're hard to debug so the compile-time constraints are particularly helpful. Features like async/await are perfect for modelling interactions with hardware peripherals, etc. But there are still a lot of rough edges. Most embedded development with Rust is still relying on unstable nightly features (particularly more advanced const evaluation). Although the recent stabilisation of GATs helps a lot.
Basically every single piece of software that matters is a C library or is exposed through a C API, because that's what other languages hook into, including Rust.
Heck, right this second I'm working on a piece of software that needs to talk to Java and Python simultaneously, so C++ with extern C it is.
Using memory safe languages when you can is good advice, but it's kind of complicated to get to a point where everything is guaranteed safe.
I don't disagree, and for that reason the transition will be slow, but I still think it will happen. The benefits are too great to ignore, or they eventually will be. Nobody's going to want to use insecure foundational libraries once secure ones are available. And they're already being written.
> Heck, right this second I'm working on a piece of software that needs to talk to Java and Python simultaneously, so C++ with extern C it is.
For what it's worth, Rust is entirely viable (and arguably easier than C++) in this space right now. It's also using extern C under the hood, but there are libraries like "pyo3" and "jni" which will deal with the unsafety for you and provide you with higher-level bindings. In practice you don't lost much safety using this approach.
Or even GraalVM which is polyglot between the two languages and can even optimize across language boundaries.
The right tools mater. The memory safe stuff above was autosar, so not something often discussed here. Rust is getting interest from the above team but after the above burn they are slow to try new things.
Building everything performance-critical with immature languages is not a viable alternative. But building with modern C++ is one.
But have they written their browsers with memory safe languages? I thought Firefox was the only one.
It was funny, I went to see my optometrist the other day and found out he's gotten into Arduino programming but he hates C/C++, particularly the way pointers work. I told him I liked AVR8 assembly a lot better. It's not safe, but I really get to enjoy the large register file and don't have my CPU doing meaningless activities to maintain C calling conventions.
D has been making steady progress towards being 100% memory safe when not using the GC (it's already memory safe if you stick to the GC).
The biggest memory safe feature is array overflow checking, and D has had that since its inception.
“CHERI extends conventional hardware Instruction-Set Architectures (ISAs) with new architectural features to enable fine-grained memory protection and highly scalable software compartmentalization. The CHERI memory-protection features allow historically memory-unsafe programming languages such as C and C++ to be adapted to provide strong, compatible, and efficient protection against many currently widely exploited vulnerabilities.”
https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
I forgot the details but iirc it’s not too much work to recompile programs for the architecture.
It was discussed on HN before, e.g. https://news.ycombinator.com/item?id=30007474
Is there any information available to assess what portion of that 70% was, or could have been, identified through static code analysis, sanitizers and other memory-safety techniques that can be applied in a bulk / automated manner?
Conspiracy: The NSA has compromised all those languages' runtimes to spy on whatever is being run and passed through them. After all, that Utah datacenter[0] isn't going to fill itself.
[0] https://en.wikipedia.org/wiki/Utah_Data_Center
Edit: comprised -> compromised
As for that Datacenter in Utah - it is a large Government project. The idea that the US Government is efficient with its resources or that its operatives are trying to maximize the use of their resources is not well supported by historical precedent. If the project is written off as yet another make-work job project for a reliably red state then I am sure we can all sleep well knowing that our tax dollars have been well spent.
1) do black hat shit and risk prison time for gains that are hard to realize
2) work in white hat security and get paid a ton of money
3) work for the government and make very little money, but get to do black hat shit with impunity
It's pretty easy to imagine that the people submitting applications to work for the NSA have no interest in protecting the US from big bad overseas hackers.
1. Enjoy shooting guns and driving fast.
2. Have an interest in protecting the US.
While this topic is about the NSA I feel this are relevant questions:
Why do we still have a FDA given they fail so regularly to catch food and drugs that harm people?
Why do we still have a FTC given they've fail so regularly to prevent monopolistic behavior from telecoms?
Why do we still have a FBI given they fail so regularly to prevent mass shootings and domestic terror attacks?
Why do we still have a NSA given they fail so regularly at sharing information allowing foreign entities penetrating our financial and tech sectors?
Surely you recognize at some point inefficiency must give way to the question, has this been done intentionally? Especially since that is supported historically.
The question at hand is: Is a recommendation to use memory-safe programming languages evidence that those languages are less safe than we previously thought?
There are two competing notions:
A. This being announced now is evidence that the NSA has recently succeeded in finding a way to subvert the security guarantees of rust.
B. This being announced now is evidence that the good actors (or actors who want to appear good) in the NSA have finally gotten through the red tape to do what is nominally their jobs.
Their track record is spotty at best, and has only gotten worse over time. So to the extent that they are recommending using memory safe languages, that's great...it's advice that would be corroborated by other institutions, researchers, and practitioners. But the moment they recommend a specific set of technologies to use, that should give you pause.
That being said, the report doesn't specifically recommend just those specific languages, and merely provides them as examples...so as long as I'm not in charge of securing an adversarial nation/state's infrastructure, I'm not gonna worry about the potential nefariousness of this recommendation.
and that's just a glimpse into how bad things really are
Almost everybody misunderstands NSA's defensive mandate. They aren't corporate America's QA department, they don't have a "let's find and report exploits" mission - their defensive mission applies to "national security systems" and other "defense industrial base" ones. Those are computers/networks running fairly specific tasks; they are generally not internet connected, and sitting in secure buildings with 24 hour security and surveillance, so securing them revolves around a lot of physical security and controlled access.
YOU don't have one of these systems, corporation XYZ doesn't have one, there is no requirement NSA disclose jack shit to anybody unless they want to. And in the ETERNALBLUE case one of their tools leaked so they helped head off a lot of problems by voluntarily telling Microsoft about it.
As for who is responsible for this - I thought all the people here are free market worshipers. If Silicon Valley tech companies, one of the richest class of private enterprises in the world, need what are effectively government subsidies to cover their bug ridden insecure products, well that sounds like multiple market failures to me.
From HN comment guidelines:
> Please don't use Hacker News for political or ideological battle. It tramples curiosity.
"These inherent language features protect the programmer from introducing memory management mistakes unintentionally. Examples of memory safe language include C#, Go, Java®, Ruby™, Rust®, and Swift®."
I don't think there's any conspiracy, but it is interesting they don't mention JS or Python.
[1]https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...
Its arrays carried their size and range with them so you could safely iterate over them and safely (well, you'd get a runtime error at least versus C's "I trust you" model) access their elements. You had tasks and rendezvous since Ada 83 which could be used to protect access to data across other tasks (this was improved later with protected types in Ada 95).
You could tightly control, in the language not at runtime, the memory layout of records which was useful for over-the-wire protocols. With C you couldn't guarantee a particular packing for a struct would be uniform across compilers, with Ada you could. This also helps reduce bugs because you can apply DRY properly, in C you have to implement marshaling and unmarshaling yourself, in Ada it was just a given.
It's a very underrated language, mostly discounted because, it turns out, people are more into fashion and style than substance. "Eww, it uses keywords like `begin` and `procedure`" seems to be the #1 reason for rejecting it anymore, rather than any serious analysis.
Already-safe code remains safe if you wrap it with unsafe.
The implications to a code reviewer don't change much from that, however.
If course no one wants to ship actually unsafe code, and it is very rare to do it in Rust or modern C++ programs. But it is depressingly common in C programs and mostly-old programs like Chromium, and in the C libraries that programs of all kinds still depend on.
> Even with a memory safe language, memory management is not entirely memory safe. [...] Memory safe languages can also use libraries written in non-memory safe languages and thus can contain unsafe memory functionality. Although these ways of including memory unsafe mechanisms subvert the inherent memory safety, they help to localize where memory problems could exist, allowing for extra scrutiny on those sections of code.
Which I suppose is a reasonable way to put it. It's been said elsewhere, but my read of this document is that this is not a _definitive_ list of languages you should use, but rather a list of languages that make it much more difficult for programmers to introduce memory-safety bugs.
Maybe they're using the other golden rule: All languages starting with a P are old, crusty and should be avoided.
Anyway, even without C extensions a malicious input might trigger a memory related vulnerability in the interpreter. A compiled program written in a memory safe language could suffer from a compiler bug. Did it happen to Go and Rust?
Really, in the long term, "unsafe" and FFI interfaces should be removed from C#, Java, and Rust. That's the only way to be sure. in fact, I'd be willing to bet that in the short to medium term, with this recommendation, government contractors will soon be required to submit code that does not use these facilities. If you can't do it in C#, use Rust, if you can't do it in Rust, use Java, but you probably will no longer be allowed to pull in that wiz-bang c++ library.
It’s essential to doing many things.
I think they may simply be the first ones that came to the writer's mind.
From wiki: > Memory safety is the state of being protected from various software bugs and security vulnerabilities when dealing with memory access, such as buffer overflows and dangling pointers
Dart has isolates, so I thought it was memory-safe. But searching for buffer overflow or dangling pointer on dart's github repo returns results, so I'm still left wondering.
For this reason, experts like Schneier [1] have long advocated that the NSA be broken up so that these two missions do not fall under the same agency.
[1] https://www.schneier.com/blog/archives/2014/02/breaking_up_t...
Responsibility (issue advisories) for unclassified, commercial, non-defense internet is a confusing mess split between Commerce (NIST, https://csrc.nist.gov/about), DHS (CISA, https://www.cisa.gov/cybersecurity), Energy (CESER, https://www.energy.gov/ceser/cybersecurity if it is related to energy infrastructure), etc.
Throw in other agencies like DISA (https://disa.mil/About/Our-Work) as appropriate.
NSA's defensive mission is about securing National Security Systems. These have a fairly specific definition, and are not running in the average business.
I think the only instance of this kind of thing for which there is evidence is the elliptic curve debacle?
But this is the NSA, some amount of suspicion is always healthy.
honi soit qui mal y pense, but I spontaneously had the same thought when I read that.
You can leave a whale sized implementation hole in the finest of Rust applications!
Now, I know what you're thinking: "Yeah, the definition of 'compromised' is what I meant when I said 'You mean "compromised"?'. Why do you have to be so pedantic?"
Perhaps you are correct. Maybe it's better to not correct people on the internet when what they were saying is technically incorrect, but otherwise understandable.
- A David Lynch biopic on Terry Davis.
If there is someone that knows how to protect yourself from the glowies, it's the creator of Holy C
Dig deeper if you dare.
Rust is safer than C++ because it does “opt-out” of memory safety, rather than modern C++ which is more “opt-in”
But Rust (other than for threads) is definitely not more memory safe than Go/Java etc. Safe rust code can still memory leak. Unsafe rust code can have memory errors (and does frequently) that those others would stop.
> Safe rust code can still memory leak.
Which is not at all a violation of memory safety, so is moot here.
> Unsafe rust code can have memory errors (and does frequently) that those others would stop.
Unsafe C#, unsafe Java, safe Go, Python all suffer from the same types of memory errors.
> What’s kinda annoying about comment sections on these articles is it shows how many people have opinions on this topic that they know only a bit about.
I'd invite you to pause and ask yourself if you know as much about the topic as you think you might, as there are either clear misunderstandings or intentional misleadings about these languages in your very short post.
https://go.dev/doc/articles/race_detector
Caveats are that it requires cgo, and it might have lower performance, so enable it during development but not during production. Also detection requires actually triggering the data race, so you need good tests to try to exercise those areas of code.
Although Rust prevents them outright, that does seem to come at the expense at some flexibility, and the actual security risk of a data race in Golang seems to be moot. For example, if you know that a shared object will only be used when the program is starting up and in single-threaded mode, then you can safely use it then without a mutex.
Even when Golang does have a data race, the race causes the program (or at least the thread) to panic and thus is probably not directly exploitable, unlike older languages.
In other words, golang changes the risk of a data race from being a vulnerability to just a program-crashing bug. [EDIT: please see comments below which indicates that this may not be true in all cases, especially if you're trying to sandbox untrusted code!]
Beyond that, Go provides special capabilities (channels) to allow communications across goroutines (which are analogous to threads but can also automatically use different cores, unlike regular threads). Channels are like a vastly improved version of Erlang's mailboxes, and are the best way to pass information between goroutines.
So, rather than use mutexes, channels are Golang's idiomatic way to eliminate data races entirely. You can pass any complex object through a channel to another listener (blocking or non-blocking) on the other side. This excellent video is actually what convinced me to switch to Go for concurrent coding (which is the only place where you run into data races anyway):
I don't believe this is true, people have demonstrated using data races to build arbitrary code execution primitives. See for example https://blog.stalkr.net/2022/01/universal-go-exploit-using-d...
Looking at the attack vector (https://blog.stalkr.net/2019/11/the-gomium-browser-google-ct...), this is a pretty tightly constrained circumstance where you are permitting an attacker to execute unknown Golang code within the context of your process. (perhaps like the Go Playground, if that's not starting a new process for each user.)
I don't personally think that's really that applicable to regular golang users, unless they're trying to sandbox Golang code somehow within the language itself. (And if you are allowing untrusted code, then it's basically game over anyway).
But it's still interesting and I added a note to my comment above about your point.
For starters just cause you “can” have memory safety issues doesn’t mean it’s the same as Rust.
I mean Rust “can” have memory safety issues, so I guess it’s equal to C++? No that’s ridiculous.
So just cause you “can” have unsafety in python doesn’t mean suddenly it’s not better than rust.
If you think memory issues mean rust is better than C++, then you must recognize all GC languages are better than rust. Rust should be used where GCs cannot.
Memory leaks are still a very real issue. Just cause they aren’t a security issue doesn’t mean they don’t affect reliability, which is important.
Memory leaks are not a memory safety error, especially when deliberate (think calling malloc without ever calling free is perfectly safe, especially if you intend it as a static duration allocation). Unintentional memory leaks like Rc/Arc cycles are not a problem that occurs in garbage collected language, true, but also not a memory safety issue, unless it's unsafe code that relies on drop() being called or something.
So if we count data races, which you mentioned, Rust is in fact safer than Java/Go.
It’s the whole case for Rust > modern C++ based on that?
Rust can have memory issues, but “it doesn’t use unsafe as much” as modern C++. Forbidding unsafe code doesn’t guarantee vulnerabilities are gone.
why is it that when talking about C++ memory safety, even a bit more is worth everything, but when talking about rust vs python, suddenly it doesn’t matter if it’s less.
Shifting the discussion to Vulns., Modern C++ is moving the goalposts a bit, don't you feel?
> Forbidding unsafe code doesn’t guarantee vulnerabilities are gone It does, because if it doesn't, or GC'd languages offer more protection, then it's a bug in rustc/spec/core libs, for all intents and purposes.
Might as well mention /proc/self/mem and other filesystem/IO related exploits, because Rust can't protect you from them, and therefore it's completely and utterly unsafe and unfit for use.
I agree no one writes actual kernels in GC languages. 100% Rust is the best choice where GCs can’t be.
I think my argument is that if you can use a GC, I think it’s considered best practice to use a GC. If you need thread safety, use a GC language like Elixir that handles concurrency well.
Like there’s no reason to act like Java community and try to force rust into every area. It’s very good at what it does, let it stay there.
Elixir is great, use elixir. I certainly am not stopping you, it's completely safe and fault tolerant. Or maybe I'm saying this because I don't know as much about Elixir/BEAM internals compared to the aforementioned languages, who knows.
If you ever go down the safe road in Rust (be it a buggy library n layers down that you use from entirely safe code), you can no longer be sure in anything, a data race is entirely undefined behavior.
Does the JVM protect you from partial reads? On Hotspot or on say, GraalVM's LLVM runtime too? Does Go? I assume they at least protect you from stale read UAFs by virtue still being traceable. (This is a genuine question).
Just like it’s harder to have a memory safety issue in rust than C++.
if you are worried about data races, use a language like elixir that’s more safe than rust and is great for concurrency.
If you are a rust dev that forces your language into areas where a GC would suffice, than you are just like C++ devs who refuse to use rust for memory safety.
You are introducing memory issues just cause you don’t want to use a better tool.
What's wrong in using Rust where a GC would suffice? Rust type system gives it a more high level feeling than go could ever provide.
Memory leaks in all languages are safe, they just slow performance and cause crashes.
Rust still memory leaks.
That it's not actually memory safe. Memory leaks are part of memory unsafety.
Rust just imposes constraints on references using the type system, so the compiler knows to emit the free in the right spot. For regular application code there's no real benefit. It's not really a systems language because of all the hidden memory allocations and lack of a stable ABI. It's garbage for embedded because of all the gratuitous copies you have to make to appease the borrow checker. It blows up your memory budget.
Can't disagree, naive garbage collected code would outperform naive Rust code that allocates Strings and Vecs up the wazoo.
And performance isn't a real issue with simple CRUD/ORM-type services.
Wrapping business logic in newtypes and enforcing specific invariants for them and serde style "parse don't validate", can do wonders for business logic, but then again you can probably just use a garbage collected functional language with dependent typing and a bunch of other tricks in its hat, and get more mileage out of it, if that's the code you write.
> It's not really a systems language because of all the hidden memory allocations
C and C++(especially) can hide memory allocation just fine themselves.
Allocations are pretty explicit in Rust, but layers of libraries can hide those (if you don't use no_std and the like), just like in C or C++.
> lack of a stable ABI
there is the C ABI, a stable Rust ABI at any stage would just be an optimization killer and a massive PITA, ask C++. Stable ABI, international standard, and multiple implementations of the compiler, are not a requirement for a systems language.
For a language that relies on compile-time monomorphization, a stable ABI beyond what C already provides gives precious little. Swift ABI forgoes monomorphization, but it's not really a trade-off a systems language should embrace. The template header issue in C++, I won't even touch.
There are also crates in the ecosystem that can generate 2-way FFI glue code to provide a stable ABI for Rust based on extern "C".
> It's garbage for embedded because of all the gratuitous copies you have to make to appease the borrow checker. It blows up your memory budget.
We use embedded Rust on a memory constrained MCU and besides slightly increasing the maximum stack size (because less is allocated on the heap), memory budget is not an issue we have. And in LLVM 16, Rust's stack usage will decrease even more, due to recent optimizations.
You don't need to use "gratuitous copies", you can statically allocate just fine, and if your value is ephemeral and is read/mutated by multiple threads, heap allocating with reference counting is just fine.
(Not necessarily "better" overall, but a better choice for certain applications.)
Both are better than C but I’d expect a good programmer to be more productive in Rust and to avoid more logic errors (which may or may not be security issues), not to mention the many problems caused by widely used open-source libraries written during the bad old days which have extensive dependencies and often enable risky behaviors by default. Culture isn’t a core language feature but it matters.
A race condition might, but even then, I'm not sure how likely that is to result in a vulnerability in a garbage collected language.
This is not generally true of other languages, where it is allowed for the compiler to do whatever it wants in these cases, meaning that once you go down the happy path, nothing can be guaranteed. Also, safe rust preventing data races is again not that big of a thing because if you want to use the same memory region (not read-only) from multiple threads you will have to use unsafe either way.
Rust can have double-frees and some of the most serious memory safety errors that those cannot.
Basically, I’d say that at fond point this gets to be a lot more complicated because you’re talking about which sets of features & cultural practices make you more or less likely to make exploitable errors. Does using a GC buy you enough to balance out the complexity fetish common in the open source Java world? Which is safer probably depends on what type of projects you work on.
Isn’t the whole argument rust vs C++ that rust gives you memory safety even though it’s more complex?
Like if you can tolerate memory issues all of the sudden to avoid complexity then there was no argument against C++ in the first place.
That's also why I mentioned culture: for various reasons, a lot of Java programmers sought ways to make tons of behaviour configurable which also means that there's both plenty of scope for log4j-style mistakes and lots of optional behaviours which might be exploitable even if few people use them. Rust's culture tends not to encourage that kind of thing as much so even though certain types of errors are possible in any language they're not equally common.
## Hardware
- Memory protection: https://en.wikipedia.org/wiki/Memory_protection
- NX Bit: https://en.wikipedia.org/wiki/NX_bit
- Can non-compiled languages (e.g. those with mutable code objects like Python) utilize the NX bit that the processor supports?
- Can TLA+ find side-channels (which bypass all software memory protection features other than encryption-in-RAM)?
- How do DMA and IOMMU hardware features impact software memory safety controls? https://news.ycombinator.com/item?id=23993763
- DMA: Direct Memory Access
- DMA attack > Mitigations: https://en.wikipedia.org/wiki/DMA_attack
- IOMMU: I-O Memory Management Unit; GPUs, Virtualization, https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_ma...
- Kernel IOMMU parameters: Ctrl-F "iommu": https://www.kernel.org/doc/html/latest/admin-guide/kernel-pa...
- RDMA: Remote direct memory access https://en.wikipedia.org/wiki/Remote_direct_memory_access
## Software
- Type safety > Memory management and type safety: https://en.wikipedia.org/wiki/Type_safety#Memory_management_...
- Memory safety > Types of memory errors: https://en.wikipedia.org/wiki/Memory_safety#Types_of_memory_...
- Template:Memory management https://en.wikipedia.org/wiki/Template:Memory_management
- Category:Memory_management https://en.wikipedia.org/wiki/Category:Memory_management
- Reference (computerscience) https://en.wikipedia.org/wiki/Reference_(computer_science)
- Pointer (computer programming) https://en.wikipedia.org/wiki/Pointer_(computer_programming)
- Smart pointer (computer programming) in C++: unique_ptr, shared_ptr and weak_ptr; Python: weakref, Arrow Plasma IPC, https://en.wikipedia.org/wiki/Smart_pointer
- Manual Memory Management > Resource Acquisition Is Initialization https://en.wikipedia.org/wiki/Manual_memory_management#Resou...
- Resource acquisition is initialization (C++ (1980s), D, Ada, Vala, Rust), #Reference_counting (Perl, Python (CPython,), PHP,) https://en.wikipedia.org/wiki/Resource_acquisition_is_initia...
- Ada > Language constructs > Concurrency https://en.wikipedia.org/wiki/Ada_(programming_language)#Con...
- C_dynamic_memory_allocation#Common_errors: https://en.wikipedia.org/wiki/C_dynamic_memory_allocation#Co...
- Python 3 > C-API > Memory Managment: https://docs.python.org/3/c-api/memory.html
- The Rust Programming Language > 4. Understanding Ownership > 4.1. What is Ownership? https://doc.rust-lang.org/book/ch04-00-understanding-ownersh...
- The Rust Programming Language > 6. Fearless Concurrency > Using Message Passing to Transfer Data Between Threads https://doc.rust-lang.org/book/ch16-02-message-passing.html#...
> One increasingly popular approach to ensuring safe concurrency is message passing, where threads or actors communicate by sending each other messages containing data. Here’s the idea in a slogan from the Go language documentation: “Do not communicate by sharing memory; instead, share memory by communicating.”
> To accomplish message-sending concurrency, Rust's standard library provides an implementation of channels. A channel is a general programming concept by which data is sent from one thread to another.
> You can imagine a channel in programming as being like a directional channel of water, such as a stream or a river. If you put something like a rubber duck into a river, it will travel downstream to the end of the waterway.
- The Rust Programming Language > 15. Smart Pointers > Smart Pointers: https://doc.rust-lang.org/book/ch15-00-smart-pointers.html
- The Rust Programming Language > 19. Advanced Features > Unsafe Rust: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
- Secure Rust Guidelines > Memory management, > Checklist > Memory management: https://anssi-fr.github.io/rust-guide/05_memory.html
- Go 101 > "Type-Unsafe Pointers" https://go101.org/article/unsafe.html https://pkg.go.dev/unsafe
- https://github.com/rust-secure-code/projects#side-channel-vu...
- Segmentation fault > Causes, Examples, : https://en.wikipedia.org/wiki/Segmentation_fault
- "CWE CATEGORY: Pointer Issues" https://cwe.mitre.org/data/definitions/465.html
- "CWE CATEGORY: Memory Buffer Errors" https://cwe.mitre.org/data/definitions/1218.html
- "CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer" https://cwe.mitre.org/data/definitions/119.html
- "CWE CATEGORY: SEI CERT C Coding Standard - Guidelines 08. Memory Management (MEM)" https://cwe.mitre.org/data/definitions/1162.html
- "CWE CATEGORY: CERT C++ Secure Coding Section 08 - Memory Management (MEM)" https://cwe.mitre.org/data/definitions/876.html
- SEI CERT C Coding Standard > "Rule 08. Memory Management (MEM)" https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pa...
- SEI CERT C Coding Standard > "Rec. 08. Memory Management (MEM)" https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pa...
- Invariance (computer science) https://en.wikipedia.org/wiki/Invariant_(mathematics)#Invari...
- TLA+ Model checker https://en.wikipedia.org/wiki/TLA%2B#Model_checker > The TLC model checker builds a finite state model of TLA+ specifications for checking invariance properties.
- Data remnance; after the process fails or is ended, RAM is not zeroed: https://en.wikipedia.org/wiki/Data_remanence
- Memory debugger; valgrind, https://en.wikipedia.org/wiki/Memory_debugger
- awesome-safety-critical https://awesome-safety-critical.readthedocs.io/en/latest/#so... ; Software Safety Standards, Handbooks; Formal Verification; backup/ https://github.com/stanislaw/awesome-safety-critical/tree/ma...
- > Additional lists of static analysis, dynamic analysis, SAST, DAST, and other source code analysis tools: https://news.ycombinator.com/item?id=24511280
List of [SGX,] vulnerabilities: https://en.wikipedia.org/wiki/Software_Guard_Extensions#List...
Protection Ring: https://en.wikipedia.org/wiki/Protection_ring ... Memory Segmentation: https://en.wikipedia.org/wiki/Memory_segmentation
.data segment: https://en.wikipedia.org/wiki/Data_segment
.code segment: https://en.wikipedia.org/wiki/Code_segment
NX bit: https://en.wikipedia.org/wiki/No-execute_bit
Arbitrary code execution: https://en.wikipedia.org/wiki/Arbitrary_code_execution :
> This type of attack exploits the fact that most computers (which use a Von Neumann architecture) do not make a general distinction between code and data,[6][7] so that malicious code can be camouflaged as harmless input data. Many newer CPUs have mechanisms to make this harder, such as a no-execute bit. [8][9]
> - Memory debugger; valgrind, https://en.wikipedia.org/wiki/Memory_debugger
"The GDB developer's GNU Debugger tutorial, Part 1: Getting started with the debugger" (2021) https://developers.redhat.com/blog/2021/04/30/the-gdb-develo...
"Debugging Python C extensions with GDB" (2021) https://developers.redhat.com/articles/2021/09/08/debugging-... & "Python Devguide" > "GDB support" https://devguide.python.org/advanced-tools/gdb/ :
run, where, frame, p(rint),
py-list, py-up/py-down, py-bt, py-locals, py-print
/? site:github.com inurl:awesome inurl:gdb
https://www.google.com/search?q=site%3Agithub.com+inurl%3Aaw.../? vscode debugger: https://www.google.com/search?q=vscode+debugger
/? juyterlab debugger: https://www.google.com/search?q=jupyterlab+debugger
Ghidra: https://en.wikipedia.org/wiki/Ghidra
> Ghidra can be used as a debugger since Ghidra 10.0. Ghidra's debugger supports debugging user-mode Windows programs via WinDbg, and Linux programs via GDB. [11]
Ghidra 10.0 (2021) Release Notes: https://ghidra-sre.org/releaseNotes_10.0beta.html
"A first look at Ghidra's Debugger - Game Boy Advance Edition" (2022) https://wrongbaud.github.io/posts/ghidra-debugger/ :
> - Debugging a program with Ghidra using the GDB stub
> - Use the debugging capability to help us learn about how passwords are processed for a GBA game
/? site:github.com inurl:awesome ollydbg ghidra memory https://www.google.com/search?q=site%3Agithub.com+inurl%3Aaw...
Memory forensics: https://en.wikipedia.org/wiki/Memory_forensics
awesome-malware-analysis > memory-forensics: https://github.com/rshipp/awesome-malware-analysis/blob/main...
github.com/topics/memory-forensics: https://github.com/topics/memory-forensics :
- microsoft/avml: https://github.com/microsoft/avml :
/dev/crash
/proc/kcore
/dev/mem
> NOTE: If the kernel feature `kernel_lockdown` is enabled, AVML will not be able to acquire memory.Sure, I introduced my share of memory bugs in C++ code early in my career when the standard was older and the (static analysis) tools were missing, but working with the modern C++ ecosystem now is a pleasure, and I don't want to have a hand tied behind my back and locked into the playpen with the Tide Pod gourmands for "safety". </rant>
I see how Rust is on that list.
I don't get how the other languages are on that list. I mean, yes, I guess they're marginally better than C and C++ at memory-safety, but... just barely...?
Like... this report?
https://msrc-blog.microsoft.com/2019/07/18/we-need-a-safer-s...
In fact some languages are even safer (e.g. Scheme and various Lisp implementations don't have integer overflows due to having bignums by default).
But, the borrow-checker seems to be significantly safer than anything else I've read about. Having no null pointer sounds very smart...
All those other languages cannot. Rust is much less safe than a GC language in terms of memory.
We're using very different definitions of those words, I guess.
https://slashdot.org/story/07/11/17/0552247/c-memory-leak-to...
Keep in mind by turning off the GC, how have now made C# just as safe as rust, not unsafer.
Way easier in C# to avoid that issue. Just don’t use reference counters and use GC.
No way to avoid that in Rust. If you need many references, you must use ARC.
And worst case, there's always jRuby.