3 ms·
> This code makes the (reasonable) assumption that the number of properties stored directly in a JSObject must be less than the total number of properties of th
by vlovich123 3y ago
> This code makes the (reasonable) assumption that the number of properties stored directly in a JSObject must be less than the total number of properties of that object. However, assuming these numbers are simply stored as integers somewhere in the JSObject, an attacker could corrupt one of them to break this invariant. Subsequently, the access into the (out-of-sandbox) std::vector would go out of bounds. Adding an explicit bounds check, for example with an SBXCHECK, would fix this.
> Encouragingly, nearly all "sandbox violations" discovered so far are like this: trivial (1st order) memory corruption bugs such as use-after-frees or out-of-bounds accesses due to lack of a bounds check. Contrary to the 2nd order vulnerabilities typically found in V8, these sandbox bugs could actually be prevented or mitigated by the approaches discussed earlier. In fact, the particular bug above would already be mitigated today due to Chrome's libc++ hardening. As such, the hope is that in the long run, the sandbox becomes a more defensible security boundary than V8 itself
- wavemode 3y agoIt's still not clear to me what Rust feature would prevent what specific vulnerability here. Rust has bounds-checked and non-bounds-checked array accesses depending on the developer's preference, and so does C++. If there's some point you're making with these quotes you're going to need to simplify it for me since I'm not following.
- rcxdude 3y agoThe defaults are switched though: C++ is unchecked by default, Rust is checked by default.
- tubthumper8 3y ago> Rust has bounds-checked and non-bounds-checked array accesses depending on the developer's preference, and so does C++ You're making it sound like these are the same, the difference is the defaults Unsafely accessing an element in C++ vec[i] Unsafely accessing an element in Rust unsafe { vec.get_unchecked(i) } One of these is screamingly obvious that something potentially unsafe is happening and should be audited more closely, that's the real difference. The cause of potential memory issues is isolated and searchable in `unsafe` blocks rather than being potentially anywhere
- wavemode 3y agoSo the Rust feature is "screaming obviousness"? Your argument is that the advantage of rewriting the module in Rust is that finding array accesses is visually easier? Why not just use grep?
- vlovich123 3y agoIt's not just that. It's that you can also add `#![forbid(unsafe_code)]` to your crate. Now you know there's 0 potential memory safety issues of any kind. Keep in mind that failed bounds checks are only 1 memory safety possibility for C++. Another common one is UB behavior which abounds all over the place in C++. The only language security issue you have to worry about with safe Rust is that integers overflow by default in release mode which means you need to explicitly annotate summations that could cause a security exploit with `saturating_X`, `checked_add`, or `wrapping_add` depending on what behavior you want when you exceed the integer range bounds. In cases where security by default is more important, setting `overflow-checks` to `true` in the Cargo profile is better - that way you have to explicitly opt-in to wrapping behavior if you want more performance in the hot path.
- tubthumper8 3y agoI'm not on the V8 team, so can't say why grep didn't find the vulnerabilities. That would perhaps be a good suggestion to make to them!
- olliej 3y agoWell that's just false in this context. vec[i] Is safe in v8, blink, jsc, webkit, etc. Rust has a huge number of benefits over c++, but it hurts your argument if you refuse to acknowledge the actual environment the C++ is being used in and make objectively incorrect statements. It implies a lack of understanding of C++ and sounds like all you're doing is parroting other people's critiques without understanding the core issues, which undermines your message. That said it's still not particularly relevant here, because the issues being presented are bugs in the runtime. e.g. the runtime logic and state results in erroneous behavior. The bugs being discussed are not "you did not use a safe vec" or "you did not use Rc", it's "the size or bounds check in vec is incorrect" or "the ref counting in Rc is incorrect". Rust does not inherently stop those the runtime from having bugs, it simply statically limits where the exposure to unsafe operations can occur. That's super relevant to program safety, but it's not relevant to safety in the JS VM runtime, where they're performing the operations that would be unsafe{} in rust as well.