4 ms·
The first example uses a "unsafe" method. I'm not very familiar with rust, but isn't this an inherently "bad thing"?
by matt_wulfeck 10y ago
The first example uses a "unsafe" method. I'm not very familiar with rust, but isn't this an inherently "bad thing"?
- stirner 10y agoAll C functions are considered unsafe, because they don't have the Rust safety guarantees. Every function in the normal libc crate is marked unsafe.
- dikaiosune 10y agoNot an inherently bad thing, really. The unsafe keyword has two meanings: 1. An unsafe block tells the compiler "trust me, I know this is unsafe and I know how to do it safely" 2. An unsafe function tells the compiler "this is unsafe! it needs to be put inside another unsafe function or an unsafe block" So an unsafe block essentially terminates an unsafe call chain. There are a bunch of things which are inherently marked as unsafe in Rust, usually because the compiler can't reason about them, like dereferencing a raw pointer as opposed to a borrow-checked Rust reference. That's what calls for an unsafe function in the case of strlen -- to only iterate over the string once we just have to assume that the pointer points to valid memory and is null-terminated, so like a lot of things in C, we just cross our fingers and go for it. The fact that Rust knows this could fail miserably is why it needs to have an unsafe block.
- xienze 10y ago> 1. An unsafe block tells the compiler "trust me, I know this is unsafe and I know how to do it safely" Right, so aren't you giving up the biggest advantage of Rust, that your code will be safe by virtue of it getting through the Rust compiler's safety checking?
- dikaiosune 10y agoYes, although there are other advantages to using Rust (about halfway down there's a "What does Rust offer here?" section that discusses in more detail). Frankly, the POSIX C standard library does not seem to have been designed with safety in mind (I don't think this requires an expert eye to see). So writing it in Rust is going to require a number of compromises on Rust's safety. Also, if I were taking this more seriously, the wildly unsafe Rust code would just be a beach head for a bottom-up conversion of a project. You have a project which uses strlen? Great, now use this Rust version. Now incrementally rewrite the strlen-using code in Rust. Now change strlen to use a Rust CString...and so on. Each time you identify a new module boundary, rewrite its dependencies in Rust, and then consume the module while preserving it's outward facing interfaces.
- xienze 10y ago> Frankly, the POSIX C standard library does not seem to have been designed with safety in mind (I don't think this requires an expert eye to see). So writing it in Rust is going to require a number of compromises on Rust's safety. That's kind of what I'm getting at. If cstdlib is inherently unsafe, and Rust cstdlib is going to be inherently unsafe, what's the point? Because of some other Rust advantages things may end up safer, but there's a lot to be said for years/decades worth of fixing existing cstdlib implementations such that you can be reasonably sure that most of what's in there is as safe as it's going to get.
- steveklabnik 10y ago> what's the point? This is directly discussed in the post, under the "What does Rust offer here?" section.
- dbaupp 10y agoThe interface will have to be `unsafe`, yes (that is, there are conditions that the code calling the functions must satisfy to avoid memory unsafety), but the internals can control this unsafety and avoid having more: libc's have vulnerabilities that are not caused by their inherently unsafe interface. The power of Rust is the ability to package up `unsafe`ty behind safe interfaces without adding unnecessary cost, so that most users don't have to be super-careful about avoiding memory corruption. This still works at a low-level like in the implementation of a libc or an operating system[1]. Also, Rust is a more expressive language, which helps avoid bugs (e.g. enums/discriminated unions means the programmer can't accidentally access invalid state), allows writing shared algorithms and data structures efficiently once instead of needing to do the bug-prone task of reimplementing (or taking a performance/safety hit with void*), and, subjectively, may be nicer to read/write . [1]: http://os.phil-opp.com/modifying-page-tables.html http://os.phil-opp.com/modifying-page-tables.html
- sitkack 10y agoSecurity and safety isn't a binary relation, it is a continuum. I think what you are experiencing is a transitive-covering fallacy. The safeties with which you are speaking aren't the same type or the same units. The argument you making is often made by people on security discussion lists to _prove_ that modifying X to make it more secure is pointless because there is still a small possibility of Y. > years/decades How long has MUSL been in development? How many programmers there are in the world?
- Retra 10y agoYour #1 should really say "I know this is safe, but since the compiler can't prove it, you'll have to trust me." That is, using unsafe doesn't mean you're doing anything unsafe, only that the rust compiler doesn't model why it is safe.
- steveklabnik 10y agoIt is not inherently a bad thing. In fact, it's very important for Rust to be able to accomplish its goals. As a systems language, we cannot dictate what we wish the machine to be; it doesn't follow our rules. Unsafe allows for three things: enable extending Rust's guarantees by allowing for humans to vouch for code, the ability to encapsulate these behaviors into a safe interface for users, and give them clear indicators of what to audit if and when they fail at it :). It's also worth noting that "unsafe" doesn't mean "anything goes." It enables extra behaviors. Regular old references are still borrow checked inside an unsafe block; unsafe unlocks the ability to dereference a raw pointer. In this case, because you're getting a raw pointer from C, unsafe has to be used: Rust can't know if C is playing by the rules.
- quotemstr 10y ago> As a systems language, we cannot dictate what we wish the machine to be; it doesn't follow our rules. Except aborting on OOM. Rust's stdlib can have an opinion about that.
- steveklabnik 10y agoSure. Our opinion is that we like our decision here. Luckily, that's only the standard library, not the language. But, I have a feeling we've been down this road before...
- tangent128 10y agoWhen you are dealing with pointers (which is a requirement to implement the API of C's stdlib), you are in unsafe territory. Fortunately, any user of the C stdlib (including other languages) already expects it to be unsafe.
- kbenson 10y ago> Fortunately, any user of the C stdlib (including other languages) already expects it to be unsafe. Yes, but it may be better to phrase it as "Fortunately, any user of the C stdlib already expects it to be unsafe by the standard and definition Rust uses". People often have their own idea of what unsafe is, and without making it explicitly clear, you might get people objecting to what is an obviously true statement purely because of a terminology mismatch.
- chriswarbo 10y agoFrom the article: > All of these are built with generally pretty unsafe code (not just in unsafe blocks, but using lots of pointer offsets and completely opting out of Rust’s ownership system). That said, Rust has already forced me to clarify a bunch of ambiguous type casts and other interesting things. I like the explicitness it has over the C with regard to integer and pointer types and operations, although I’m sure that is at least in part because I’m not very familiar with C.