8 ms·
> Rust has checked multiplication enabled by default in debug builds, and regardless of that the OOB wouldn't be possible. That bug is only triggered by an unr
by attractivechaos 10y ago
> Rust has checked multiplication enabled by default in debug builds, and regardless of that the OOB wouldn't be possible.
That bug is only triggered by an unrealistic corner case (username longer than 512MB). Run-time check in debug build won't help unless you realize the possibility before hand and put a unit test for that. I am more interested in the second part of your comment: "the OOB wouldn't be possible". How does rust protect against such integer overflow caused by multiplication? Thanks in advance.
- anp 10y agoBy default rust doesn't allow out of bounds indexing (indexing and iteration are checked, although bounds checks are often optimized out), you have to explicitly write unsafe code to read off the end of an array or vector.
- caconym_ 10y agoCan you elaborate on bounds checks being optimized out? Is it only in certain situations where compiler can prove that they are completely unnecessary? Otherwise, they can't be relied on, so what's the point of having them at all?
- steveklabnik 10y agoYes, if the compiler can prove they're not needed, then it can remove the checks. But it has to prove it.
- jerf 10y ago"That bug is only triggered by an unrealistic corner case (username longer than 512MB)." What makes you call that an "unrealistic" case? You're probably imagining some sort of world where a randomly distributed set of usernames are sent to this function drawn from the distribution of "real usernames that people use". Since 0 of them are longer than 512MB, you intuitively assume a 0 probability of exploit. But in the security world, that's the wrong distribution. You have to assume a hostile, intelligent adversary. It isn't hard at all to construct a case of some web service allowing you to specify remote resources accessible with a username & password of your choosing (not corresponding to the username you're using to log in), an attacker specifying one of their own resources, reading the incoming headers to notice that you're using a vulnerable version of libcurl, and stuffing 512MB+exploit into the username field of your web app. If you don't add any other size restrictions between the attacker and the libcurl invocation, they may well pass it right in. (And your same intuition will lead you to not put any size restrictions there; "why would anybody have a multi-megabyte username?" You won't even have thought the question explicitly, you just won't put a length restriction on the field because it'll never even cross your mind.) By penetration standards, that doesn't even rise to the level of a challenge.
- ambulancechaser 10y agoI think you missed the point of the post you are responding to. That person understands the value of the bug, and is just pointing out that Rust runs with unchecked math in production and would therefore be just as vulnerable in production. The benefit would come from it running with checked math in debug mode, but you, as the parent posted noted, would have to have a unit test or an integration test that realized this vulnerability to begin with and tried to exploit it. The use of "unrealistic" was meant in the sense that you wouldn't think of it, not that you shouldn't guard against it once known.
- steveklabnik 10y ago> therefore be just as vulnerable in production. I think there's two components here: yes, this might lead to a _logic bug_, but it should never lead to a _memory safety_ bug. That is, to get that CVE, you need both, and Rust will still protect you from one.
- ars 10y agoNo, by default rust production builds run without memory safety turned on. Edit: I believe I confused rust with another language.
- steveklabnik 10y agoWhat do you mean?
- jerf 10y agoMy point is that it is not an unrealistic case. In a security context, it is perfectly realistic.
- castis 10y agoI agree that the case is perfectly realistic. > How does rust protect against such integer overflow caused by multiplication? To me, the question was whether or not Rust would have been able to natively protect against this, considering it was a runtime issue?
- simias 10y agoI think you can opt-in the checked arithmetic in release mode if you can stomach the performance cost. Anyway, the buffer overflow itself is: >If this happens, an undersized output buffer will be allocated, but the full result will be written, thus causing the memory behind the output buffer to be overwritten. In Rust's case the output buffer would be returned into a dynamically sized type, probably a Vec<>. Attempts to put more data in the Vec than it can hold would either cause a runtime error or cause the Vec<> to reallocate (which could cause a performance issue, or maybe even a DoS if you could cause the system to allocate GBs of memory, but it wouldn't allow access to invalid memory). So maybe something like: /* XXX potential multiplication overflow */ let mut buf = Vec::with_capacity(insize * 4 / 3 + 4); while let Some(input) = get_input() { // Reallocs when capacity is exceeded buf.extend_from_slice(input); } So even if the multiplication overflow is not caught it's by design impossible to have a buffer overrun in Rust.
- dredmorbius 10y agoReality is unrealistic. https://medium.com/@blakeross/mr-fart-s-favorite-colors-3177a406c775 https://medium.com/@blakeross/mr-fart-s-favorite-colors-3177...