Live data from Hacker News

Experimenting with Rust in Chromium

chromium.googlesource.com

81–90 of 115 posts

Re: Experimenting with Rust in Chromium

#81
post #39

Earlier quoted context omitted.

Perhaps, but in the in the ancient past before STL was standardized, Chrome didn't exist. 10 years ago (when the parent mentioned they were still at Google) c++11 was already out.

Ten years ago was 2012. C++11 came out in 2011. Do you believe a big codebase like Chrome would be converted to C++11 less than one year after the spec was published? I find that unlikely but i never worked on such a big codebase so i wouldn't know.

> C++11 came out in 2011

C++0x was a thing, with varying levels of support from all major compilers, for years before C++11 was finally ratified.

In the context of my original comment though, no matter how dated the code base, I think it unlikely that Chrome was using any variant of std::string that had an implicit conversion operator for const char* such that string could be passed as a parameter to a function taking const char* without needing to call c_str().

Re: Experimenting with Rust in Chromium

#82
post #58

Earlier quoted context omitted.

Yes, I believe literally every single 'in the wild' exploit has abused memory unsafety, as well as hundreds of vulnerabilities every year.

That's strange... if they'd written the code in a memory safe language, say, Java... there wouldn't be any vulnerability? I don't know... I see plenty of vulnerabilities in the Java world, no memory unsafety needed.

A security related bug often comes down to violating the principle of least power either in a technical way by introducing a leak that can be exploited with crafted input, or via design, where a human participant is assumed to be trustworthy.

I think wider memory safety, SQL injection and things like log4j are related to the former. Some aggregation of data that should be dumb and restricted is given too much trust, so data can be lifted to code and code is too powerful. In essence they are all similar, even though we don't use the same technical terms for each of them.

And yes, if a given programming environment restricts a class of operations, it is given less power so the attack surface is qualitatively smaller. Languages that restrict memory management are an example. Another one would be file/disk access, network access and so on.

Re: Experimenting with Rust in Chromium

#83
post #35

Earlier quoted context omitted.

https://www.chromium.org/Home/chromium-security/memory-safet... See "Using safer languages anywhere applicable".

Interesting that Java, Swift, and Javascript are listed there but not Go. I wonder why

Because they are relevant on the context of Android, Apple OS, and ChromeOS respectively, as the main OS languages alongside C and C++.

Re: Experimenting with Rust in Chromium

#84
post #23

Earlier quoted context omitted.

It's the 'too many string types' that helps. With C++, if you have char*'s (because you don't need to own the memory) and you pass it to a function that takes a const std::string& (because it also doesn't want to own the memory), then there will still be an implicit conversion to a temporary std::string (involving an allocation) despite neither the caller or the callee needing to own any memory. With Rust, if you hav…

This discussion is making me wonder if windows-rs [1], the crate with official Rust bindings for all Windows APIs, is doing something that's not idiomatic Rust. Specifically, for any Windows API function that takes a UTF-16 string as a parameter, the signature for that parameter is something like "impl IntoParam ". The crate then implements that trait for String and &str, so you can pass a normal Rust UTF-8 string (e…

That might hide it from the caller, but the function that receives that IntoParam type will still need to explicitly call the conversion function.

Re: Experimenting with Rust in Chromium

#85
post #23

Earlier quoted context omitted.

How would Rust help here? Isn't it famous for having too many string types?

It's the 'too many string types' that helps. With C++, if you have char*'s (because you don't need to own the memory) and you pass it to a function that takes a const std::string& (because it also doesn't want to own the memory), then there will still be an implicit conversion to a temporary std::string (involving an allocation) despite neither the caller or the callee needing to own any memory. With Rust, if you hav…

My minor, unpolished grievance with Rust's approach is that you have to do this for all kinds of types (e.g., Path vs PathBuf). It's tedious to have to write these pairs all the time, along with all of the trait implementations and so on. It almost feels like it would be nice if the type system could allow us to write `String` or `PathBuf` and automatically generate the corresponding `str` or `Path` types.

Re: Experimenting with Rust in Chromium

#86
post #58

Earlier quoted context omitted.

Yes, I believe literally every single 'in the wild' exploit has abused memory unsafety, as well as hundreds of vulnerabilities every year.

That's strange... if they'd written the code in a memory safe language, say, Java... there wouldn't be any vulnerability? I don't know... I see plenty of vulnerabilities in the Java world, no memory unsafety needed.

Security isn't a binary, and the vulnerabilities that are possible in a memory safe language are a subset of those possible in a memory unsafe language. We want to minimize the number of possible vulnerabilities.

Yes, the above is a bit oversimplified: most memory-safe languages have an "unsafe" escape hatch, so technically these vulnerabilities are possible; however, these escape hatches are rarely used, explicitly opted-into, and clearly demarcated in the source code such that the number of vulnerabilities in "memory safe" languages is far smaller than "memory unsafe" languages.

Re: Experimenting with Rust in Chromium

#87
post #72

Earlier quoted context omitted.

> because C++ 98 and C++ 03 strings are both even more dangerous ... how so ? they were just CoW which is actually I think the better choice most of the time... now there are copies all over the place

CoW strings with atomic reference counting was definitely the wrong choice for a multi-core universe. The performance penalty is way too high. If you need that semantic there are other ways to get it.

> Performance pentalty way too high?

Is a single atomic increment really that expensive? I mean we are not even talking about a full memory barrier here, just the atomic increment's implied acquire and release on the single variable. Other operations not dependent on a subsequent read could still be re-ordered in both directions.

And also keep in mind that the alternative was copying the whole string instead. Which means both heap memory allocation (which is often pretty expensive, even with per-core heaps), plus the actual copying. Unless a platform has a terrible implementation of atomic increment, or you have a std::string that is frequently getting copied on multiple cores (so as to have meaningful contention), I would have expected the actual copying implementation to be slower. But I'm not super familiar with the timings of these things, so i certainly could be mistaken.

My understanding was that the change was more for about being able to set proper bounds on some operations, ensuring .c_str() is O(1), and not O(n) sometimes, and similarly with string writes, etc.

Re: Experimenting with Rust in Chromium

#88
post #72

Earlier quoted context omitted.

CoW strings with atomic reference counting was definitely the wrong choice for a multi-core universe. The performance penalty is way too high. If you need that semantic there are other ways to get it.

> Performance pentalty way too high? Is a single atomic increment really that expensive? I mean we are not even talking about a full memory barrier here, just the atomic increment's implied acquire and release on the single variable. Other operations not dependent on a subsequent read could still be re-ordered in both directions. And also keep in mind that the alternative was copying the whole string instead. Which m…

Copying short strings does not necessarily involve an allocation in implementations using short string optimization. Shooting down the cache line in a remote CPU that happens to have used a frequently-used string recently is absurdly expensive by comparison.

Re: Experimenting with Rust in Chromium

#89

Earlier quoted context omitted.

This discussion is making me wonder if windows-rs [1], the crate with official Rust bindings for all Windows APIs, is doing something that's not idiomatic Rust. Specifically, for any Windows API function that takes a UTF-16 string as a parameter, the signature for that parameter is something like "impl IntoParam ". The crate then implements that trait for String and &str, so you can pass a normal Rust UTF-8 string (e…

That might hide it from the caller, but the function that receives that IntoParam type will still need to explicitly call the conversion function.

Yes, and all those receiving functions are auto-generated as part of windows-rs.

Re: Experimenting with Rust in Chromium

#90
post #88

Earlier quoted context omitted.

> Performance pentalty way too high? Is a single atomic increment really that expensive? I mean we are not even talking about a full memory barrier here, just the atomic increment's implied acquire and release on the single variable. Other operations not dependent on a subsequent read could still be re-ordered in both directions. And also keep in mind that the alternative was copying the whole string instead. Which m…

Copying short strings does not necessarily involve an allocation in implementations using short string optimization. Shooting down the cache line in a remote CPU that happens to have used a frequently-used string recently is absurdly expensive by comparison.

The COW and short string optimizations are not mutually exclusive. If we assume short string optimization is implemented both before and after, then we are back to comparing the atomic increment to allocation. And different allocation approaches can make the cost of heap allocation differ quite substantially. I'd fully expect that some allocation approaches are cheaper than the cache line invalidation from atomic increment, but some others that tend involve a lot of pointer chasing can be rather costly.

Certainly plenty of widely copied strings are short strings, so a COW implementation that lacks the short-string optimization could very easily be a bad bottleneck for multi-core compute.

Post reply on HN