9 ms·
Rust (despite the common understanding) is not a memory-safe language in its entirety. It is a language designed to have a strict division of safe/unsafe which
by cyber_kinetist 4y ago
Rust (despite the common understanding) is not a memory-safe language in its entirety. It is a language designed to have a strict division of safe/unsafe which makes it easier for developers to compartmentalize code to achieve memory-safety.
- insanitybit 4y agoNo language in use meets your definition of memory safe.
- pclmulqdq 4y agoAda seems to fit.
- burntsushi 4y agoAda has no "unsafe"? Ada has no ffi? Ada has no escape hatches or unchecked APIs whatsoever? Does it have any pragmas that can disable safe checking? Because if it does, it's not "entirely" memory safe.
- thesuperbigfrog 4y agoAda has "unchecked" operations: Unchecked Access (unsafe pointers): http://www.ada-auth.org/standards/22rm/html/RM-13-10.html#I5733 http://www.ada-auth.org/standards/22rm/html/RM-13-10.html#I5... Unchecked Deallocations ("free"): http://www.ada-auth.org/standards/22rm/html/RM-13-11-2.html#I5783 http://www.ada-auth.org/standards/22rm/html/RM-13-11-2.html#... Unchecked type conversions (unsafe casting): http://www.ada-auth.org/standards/22rm/html/RM-13-9.html#I5708 http://www.ada-auth.org/standards/22rm/html/RM-13-9.html#I57... Ada has FFI: C / C++: http://www.ada-auth.org/standards/22rm/html/RM-B-3.html http://www.ada-auth.org/standards/22rm/html/RM-B-3.html COBOL: http://www.ada-auth.org/standards/22rm/html/RM-B-4.html http://www.ada-auth.org/standards/22rm/html/RM-B-4.html Fortran: http://www.ada-auth.org/standards/22rm/html/RM-B-5.html http://www.ada-auth.org/standards/22rm/html/RM-B-5.html Ada has pragmas to both enable more security measures or relax security measures: http://www.ada-auth.org/standards/22rm/html/RM-L.html http://www.ada-auth.org/standards/22rm/html/RM-L.html Just like in unsafe Rust, sometimes in Ada you need to turn off some security features or tell the compiler "I know what I am doing for this part" when interfacing with some hardware or similar low-level stuff.
- deleted 4y ago[deleted]
- pcwalton 4y agoAda has an FFI.
- modshatereality 4y agoAs well as address clause, unchecked_conversion and address_to_access_conversion. Extremely useful tools that give you the choice when to write risky code, and generate a compiler note exactly where such risk lives.
- insanitybit 4y agoA simple heuristic that I expect to work universally is "could I write a program that prints to my terminal on a linux machine?" and if the answer is "yes" then it does not fit.
- scj 4y agoPerhaps the problem is with the term "memory safe". No language can prevent a person from allocating a writable buffer, then reusing it without cleaning it. Do that on a server, and you have step 1 to a security vulnerability. If requests to allocate memory come faster than the garbage can be collected. Or a data container holding many/large references that will never be used. The difference between that and a lost pointer in C are moot in a practical sense. All of these _can_ be prevented. But it's programmer care, rather than the language, that prevents them. Hence, the term "memory safe" is inaccurate. "Memory safer" would be more accurate, but far less catchy.
- burntsushi 4y agoYes, but this problem exists everywhere all the time in virtually any context, even outside of technology. It's a very general problem that plagues communication. My perspective on the matter is the following: 1. We love to simplify matters down to black & white thinking with absolutist statements. 2. Attention spans are short (and probably getting shorter), so we try very hard to be pithy. 3. General seeming statements are actually narrower than they appear. 4. When taking a statement at its literal absolutist meaning leads you to an absurd conclusion, you're "supposed" to use your own judgment to interpret it imprecisely rather than ridiculously. "memory safety" fits these criteria pretty well, especially the third point. Clearly, you really can't have a programming language be practical/general-purpose while simultaneously being completely and totally "memory safe." It's just ridiculous given our current predominant operating systems and architectures. The pithiness of "memory safety" relies on you, dear reader, knowing that and interpreting "memory safety" as something more reasonable than that. > No language can prevent a person from allocating a writable buffer, then reusing it without cleaning it. Do that on a server, and you have step 1 to a security vulnerability. This is a good example of (4), where you interpret something generally, but it's actually much narrower. When folks say "memory safety," they are not referring to the problem you speak of here. The problem you speak of might be a vulnerability, but it is not, in and of itself, something that would be recognized as memory safety. A memory safety bug could lead to the circumstances you describe, but it is not necessary. (Some people like to claim that other people think memory safety is the only kind of safety that matters, but few people with any credibility actually espouse that view as far as I'm aware. But it's important to call out: if you fixed every single memory safety issue ever, you would not fix every single security or vulnerability issue.) The important life lesson here is that jargon is abound, and a good skill to pick up is knowing when to recognize it. If we go around interpreting every very literally, it's going to be a bad time. We could also stubbornly demand that everyone use crystal clear, unambiguous, precise and accurate terms all of the time everywhere so that nobody ever gets confused about anything ever again. But of course, I'm quite certain that is simply not possible.
- burntsushi 4y agoIs there any practical programming language that is memory safe in its "entirety"? Python, for example, certainly is not. It has unsafe escape hatches (via ffi, at the very least). Yet, everyone I know of says and thinks of Python as a memory safe language. I do as well. > which makes it easier for developers to compartmentalize code to achieve memory-safety The problem here is that this is incomplete. Many many many languages have achieved this before Rust. Where Rust is (somewhat although not entirely) unique is bringing this compartmentalization into a context that (mostly) lacks a runtime and garbage collection. I have no problems calling Rust a "memory safe language" precisely because I have no problems calling Java or Python "memory safe languages." What matters isn't whether the language is "entirely" memory safe. What matters is what its default is. C and C++ are by default unsafe everywhere. Rust, Java, Python and many others are all safe by default everywhere. This notion is, IMO, synonymous with the more pithy "memory safe language."
- masklinn 4y ago> It has unsafe escape hatches (via ffi, at the very least). Yep, ctypes is part of the stdlib and lets you corrupt the VM on the fly. Fun stuff like changing the value of cached integers and everything. But ctypes being a terrifying pain in the ass, people tread very carefully around it. Cffi’s a lot better though it requires an external package. At the end of the day I think I’d be more enclined to bind through pyo3 or cython than write C in python (which is what ctypes has you do without even what little type system C has, to say nothing of -Wall -Weverything).
- rraval 4y ago> But ctypes being a terrifying pain in the ass, people tread very carefully around it. I'm not sure how much people treading carefully actually translates into safety in practice. CPython in particular has ad-hoc refcounting semantics where references can either be borrowed or stolen and you have to carefully verify both the documentation and implementation of functions you call because it's the wild west and nothing can be trusted: https://docs.python.org/3.9/c-api/intro.html#reference-count-details https://docs.python.org/3.9/c-api/intro.html#reference-count... This ad-hoc borrowed vs stolen references convention bleeds into cffi as well. If you annotate an FFI function as returning `py_object`, cffi assumes that the reference is stolen and thus won't increment the ref count. However, if that same function instead returns a `struct` containing a `py_object`, cffi assumes the reference is borrowed and will increment the ref count instead. So a harmless looking refactoring that changes a directly returned `py_object` into a composite `struct` containing a `py_object` is now a memory leak. Memory leaks aren't so bad (even Rust treats them as safe after the leakpocalypse [1] [2]). It's when you go the other way and treat what should have been a borrowed reference as stolen that real bad things happen. Here's a quick demo that deallocates the `None` singleton: Python 3.9.13 (main, May 17 2022, 14:19:07) [GCC 11.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.getrefcount(None) 4584 >>> import ctypes >>> ctypes.pythonapi.Py_DecRef.argtypes = [ctypes.py_object] >>> for i in range(5000): ... ctypes.pythonapi.Py_DecRef(None) ... 0 0 0 0 0 [snip] Fatal Python error: none_dealloc: deallocating None Python runtime state: initialized Current thread 0x00007f28b22b7740 (most recent call first): File "<stdin>", line 2 in <module> fish: Job 1, 'python3' terminated by signal SIGABRT (Abort) [1]: https://rust-lang.github.io/rfcs/1066-safe-mem-forget.html https://rust-lang.github.io/rfcs/1066-safe-mem-forget.html [2] https://cglab.ca/~abeinges/blah/everyone-poops/ https://cglab.ca/~abeinges/blah/everyone-poops/
- civopsec 4y agoThen even Java is not memory safe according to the implicit standard that you allude to here since one can use the `Unsafe` class.
- deleted 4y ago[deleted]
- kaba0 4y agoNot for much longer, access has to be very explicitly specified at start time so that (deliberate) hole is getting smaller and smaller. But of course native functions is a thing (but very infrequent)
- raphlinus 4y agoThe blog speaks to this explicitly, in the "what about unsafe Rust" section. The tl;dr is that the number of unsafe sections is a small fraction of the total code size, and it's much easier to audit the usage of unsafe, as the reason to justify it is focused. Thus, the use of unsafe in Rust is not a significant driver of actual vulnerabilities. I think this has always been the goal, but it wasn't obvious at the outset that it would be achievable. The fact that we now have empirical evidence in real shipping products is significant.
- SleepyMyroslav 4y agodisclaimer. I am sympathetic to the cause. I think Android needs to address security since they are processing personal data. I like how Rust community tries to educate others on what 'memory safety' is and is not. But i am completely baffled by arguments that count number of unsafe blocks or code lines. Like this: >the number of unsafe sections is a small fraction of the total code size Code execution combinatorial effects makes number of sections or code size completely useless metrics to judge security. They do help mechanical part of auditing security in sense that they help to locate things. But locating things was never enough to judge if security is there.