
Chromium project finds that 70% of security defects are memory safety problems - solarengineer
https://www.chromium.org/Home/chromium-security/memory-safety
======
Barrin92
Reminded me of an article I read last year
([https://www.zdnet.com/article/microsoft-70-percent-of-all-
se...](https://www.zdnet.com/article/microsoft-70-percent-of-all-security-
bugs-are-memory-safety-issues/))

Interestingly enough Microsoft arrived at the same number. I think it really
stresses how hard it is to reason about memory manually. I'm still surprised
how much stuff is being written in non-safe languages even if people could get
away with a managed language.

One thing that I just recently noticed when scrolling through some github
repos is how much new software in the linux ecosystem is still written in C
despite it being probably avoidable, like flatpak.

~~~
keithwinstein
You know, I totally buy that 70% of the vulnerabilities in complex C++ code
relate to memory safety, especially in something like Chromium, which is
incredibly complex and includes a lot of third-party code that wasn't always
designed at first to be robust to untrusted input, and also fast-moving with a
ton of code added or churning every week. But I'm not sure I buy that memory-
safe languages will consequently be as beneficial for safety (especially in
other kinds of software) as that fact would suggest.

For one, not all software is like Chromium. If you look at something like
OpenSSH, the vast majority of their security holes have nothing to do with
memory safety and are just logic bugs (often caused by features that somebody
added that aren't core to the basic SSH experience, e.g. code that interfaces
with X11 or something) or protocol weaknesses. ([http://cve.mitre.org/cgi-
bin/cvekey.cgi?keyword=openssh](http://cve.mitre.org/cgi-
bin/cvekey.cgi?keyword=openssh))

The other effect is that in practice, memory-safe languages can come with
security baggage of their own. If you look at the zillions of security holes
in something like Rails or Wordpress or Django, a fair portion of them relate
to an attacker's ability to invoke sophisticated-but-unintended behaviors that
are more likely to be hiding in these managed languages (and their support
libraries) than in something like C++. E.g. CVE-2013-0156 or CVE-2013-0277 or
apparently any current Python or Ruby program that, even today, calls
yaml.load on untrusted input. That kind of "security hole from unwanted latent
functionality" is less likely to exist in C++. (I realize this is a contrarian
view not shared by the vast majority of PL/security experts, but the ones I
hang out with seem to interpret "memory-safe language" to mean "expert-written
Haskell or, if you want to slum it, Rust" and are not thinking "random
Ruby/Python/JavaScript/enterprise Java".)

Not to mention the countless high-profile security holes that have nothing to
do with memory safety, e.g. Shellshock, "goto fail", Lucky Thirteen, BEAST,
CRIME, POODLE, FREAK, Logjam, etc. Or bugs that are very relevant to Chromium
but aren't really Chromium's fault and probably don't appear on their own
list, e.g. Meltdown/Spectre etc.

~~~
saagarjha
Yes, it is important to note that switching to a memory safe language does not
magically solve all your bugs. My own personal anecdote: when I found multiple
bypasses in the sandboxing mechanism on macOS, it was not because the relevant
code was written in C++, but because the dynamic linker is a really complex
system; the things I found clearly flew under the engineer’s radar when they
were designing it and they didn’t think beforehand about how those components
interacted together. Still, being able to reduce the attack surface area to
solely be logic errors is much better than having to deal with memory safety
thrown in as well. (Similarly, languages with stricter type systems magically
get rid of issues like “you gave me a string and I wanted an int”, but the
problems of “you forgot to check the password in this one case” still remain.)

~~~
nindalf
I think reduction in the number of errors is a worthwhile goal. Switching from
C++ to a language without memory safety issues while being just as fast would
reduce the number of things the developer and code reviewer have to worry
about. They could spend more time searching for bugs in the logic, potentially
eliminating further issues.

In practice what I’ve found is that people prefer to deal in absolutes. A
large reduction in a category of bugs isn’t enough, it needs to be eliminated
altogether, they say. If it’s still possible in a contrived example, what’s
the point of investing in switching?

~~~
fpoling
Also memory-safe languages with GC allow for simpler API and design. That in
turn gives more time to think on errors in logic.

~~~
erichocean
They're simpler only if you could care less about performance. C and C++ are
primarily used in situations where you _do_ care about performance.

~~~
_ph_
Memory safety and performance are not a contradiction, they are widely
independant. Yes, some strategies like GC induce an overhead. But in the age
of multiprocessor machines, this overhead gets very much reduced by parallel
collection. And practice has shown, in programs with a lot of dynamic memory
allocation, garbage collected languages often perform even better. There are
different approaches, like memory safety by the compiler as Rust does it. And
with "performance" in mind, you shouldn't forget, that most large C/C++
programs tend to use libraries to provide some amount of safety, but those
libraries are of course adding some overhead too. Finally, the less time you
spend on questions of memory management, the more time you have to write an
actually fast program.

~~~
dirtydroog
Sorry, this is hand wavy nonsense. One counter example, we switched from
Cassandra (JVM) to Scylla (C++). It was a win in terms of both query latency
and infrastructure costs as we required fewer machines to handle the same
load.

As for having more time to write a fast program... that's funny. If you want a
fast program on something JVM based you're pretty much going to be spending
the majority of your time writing things in a way where the GC plays as little
role as possible.

~~~
murderfs
There are notable examples where garbage collection has both better throughput
and latency than manual memory collection: persistent data structures come to
mind, because in the absence of garbage collection, you have giant awful
cascades of reference count manipulation any time a structure would get freed.

You'll never actually see anyone tout the benefits of using GC for this,
though, because the performance characteristics of persistent data structures
are so horrendous compared to mutable ones, no one actually uses them in C++.

~~~
andrepd
Well yes, if you are comparing GC to refcounting then yes, gc wins.

~~~
_ph_
If your problem demands many heap allocations, GC wins also vs. manual memory
management. Heap allocation in a generational GC is as fast as stack
allocation, you don't get fragmented heaps.

~~~
pkolaczk
It is nowhere near stack allocation, please stop this nonsense. There was a
paper claiming that, but the requirement was to set heap size 7x bigger than
needed.

Stack is also very hot in cache. Memory that GC is handing allocations from is
not.

I recently ported some of Cassandra code from Java to stack-only Rust and I
got ~25x performance improvement, most from avoiding heap allocations and GC.

------
riquito
Matches closely the number of memory related security issues Firefox had in
their CSS parser before the rewrite in Rust [1]

> Over the course of its lifetime, there have been 69 security bugs in
> Firefox’s style component. If we’d had a time machine and could have written
> this component in Rust from the start, 51 (73.9%) of these bugs would not
> have been possible

Also interesting on the topic of memory safety

[https://hacks.mozilla.org/2019/01/fearless-security-
memory-s...](https://hacks.mozilla.org/2019/01/fearless-security-memory-
safety/)

[1] [https://hacks.mozilla.org/2019/02/rewriting-a-browser-
compon...](https://hacks.mozilla.org/2019/02/rewriting-a-browser-component-in-
rust/)

~~~
asjw
In this context I believe that the rewrite benefitted Firefox more than Rust

At Firefox they already knew the problem they were trying to solve using Rust,
they already wrote that software, already discovered many of the overlooked
complications involved in writing a modern browser, so, in conclusion, even a
rewrite in plain C would have solved many of the bugs.

The simple operation of rewriting the same software with previous knowledge of
how it works usually leads to simpler code (at the cost of developers time)

Firefox is also the entity that invented Rust, so it's in their best interest
to publicize it as "the final weapon" against bug, but "if we had used Rust
from the beginning these bugs would not have been possible" is just wishful
thinking.

Rust itself could not be there without the browser war and the pressure that
contemporary web puts on software that runs it

And it'been C/C++ that has driven us there

~~~
steveklabnik
> At Firefox they already knew the problem they were trying to solve using
> Rust, they already wrote that software, already discovered many of the
> overlooked complications involved in writing a modern browser, so, in
> conclusion, even a rewrite in plain C would have solved many of the bugs.

The Rust re-write was the third attempt; the first two were in C++ and failed.

~~~
chinesempire
> The Rust re-write was the third attempt; the first two were in C++ and
> failed.

AFAIK most of Firefox is still written in C++, JavaScript and C [1]

The JavaScript interpreter, which is particularly important to users perceived
speed, is entirely written in C++

[1] [https://4e6.github.io/firefox-lang-stats/](https://4e6.github.io/firefox-
lang-stats/)

~~~
steveklabnik
I am talking specifically about the style engine, which is the topic of this
sub-thread.

~~~
chinesempire
the posts linked in the beginning of the thread talk about 51 memory safety
bugs over the course of many years, from 2002 to 2018.

Stylo has been the default CSS parser starting from the beginning of 2018.

It's good that Rust could have avoided them, but is it a fair comparison?

I think that when at Firefox they started to think about a new architecture to
better enable parallelism they began improving considerably, Rust is only a
part of that.

~~~
steveklabnik
If you watch the talk I linked below, you’ll see more details. They were, and
tried with C++, and failed. Rust was key to the success.

~~~
chinesempire
> If you watch the talk I linked below

I've watched it several times over the past 2 years

And I've read the posts about writing and HTML engine in Rust when they first
came out in 2014

[https://limpet.net/mbrubeck/2014/08/08/toy-layout-
engine-1.h...](https://limpet.net/mbrubeck/2014/08/08/toy-layout-
engine-1.html)

and ported them to Elixir and still use them in my programming lessons

> Rust was key to the success.

For them

It's important to specify that Rust, built by Firefox, lead to a Firefox
success.

Just like Dart, created by Google, is the language of choice for Flutter, also
created by Google.

I know you've been working at Mozilla to work on Rust and I believe Rust is
very good, but I also think Mozilla could have used other languages, there
were a few that could led them to success, but they understood this are times
where the "means of production" aren't the machines but engineers tools, and
creating a programming language is the best way to control part of that world.

~~~
leshow
> there were a few that could led them to success

which ones? If they tried 2 or 3 times with C++ and the Rust one succeeded,
what other information would you need to have to convince you that Rust was
the differentiating factor? It seems like you just don't want to admit that
Rust was the key to their success in the project, even when you have someone
who was there telling you that it was.

We aren't going to get research study levels of replication on large projects
like this, so I don't know what standard you're looking for here.

~~~
chinesempire
> what other information would you need to have to convince you that Rust was
> the differentiating factor?

The fact that Chrome is doing just fine without it?

> t seems like you just don't want to admit that Rust was the key to their
> success in the projec

It seems like you are trying a classic ad personam, I agree that Rust was one
of the changing factor, I also wrote it, but just for Firefox, not in general.

Which is the original point of this sub-thread.

> We aren't going to get research study levels of replication on large
> projects like this

I don't think Firefox is the only large project out there. nor the largest.

------
dstaley
Not to be snarky, but my initial response to this was "Large project that uses
language known for memory safety issues discovers that most of their security
bugs stem from memory safety issues". In a more serious note, I hope this
motivates the Chromium team to invest more in Rust. While the other options
sound like good "in the meantime" solutions, switching to a language that, at
its core, is designed to prevent these sorts of issues would be a huge benefit
to society as a whole considering that Chromium is the most popular browser
engine in the world.

~~~
ridiculous_fish
Has there been any work on how to leverage Rust's strengths for a GC language
implementation? For example, Rust assumes unique ownership for mutable values;
how do you express that the value is _also_ reachable by the GC?

~~~
monadic2
If by GC you’re referring to its reference counting, either by Rc or Arc,
there is no GC reachability beyond the reference counting. The responsibility
for counting the contained object and dropping (cleanup before dealloc) is up
to the type, either Rc or Arc (a stands for atomic, not automatic, as both are
“automatic” in the sense that you never need to manually increment or
decrement a reference). the owned, mutable object would contain the type
information necessary to generate the right Rc calls ay the right time, but a
distinct type is necessary to encapsulate the behavior.

There are also escape hatches, between unsafe leaking and the RefCell type, to
provide “interior mutability”, i.e. mutable aliasing via an without the memory
safety issues which come with this. Note I have only had to use the unsafe
bits when passing memory up to a c stack.

I don’t believe there is a tracing GC implementation in the standard library,
although I’ve heard plenty of discussion and you can find some simple
implementations on crates.io. However, I would assume there would need to be
some language changes to properly account for assumptions on how the Drop
(free) functionality fires, not to mention significant backend work for
tracing to work.

~~~
ridiculous_fish
Let's put it this way: if you have a &mut to a heap allocated object (Box,
whatever), you pretend it's unique, BUT its contents are also reachable by the
global allocator, say, malloc. So it's not _really_ a unique reference.

If you allocate something new, Rust pretends it is independent, assuming that
malloc won't muck with the other objects it knows about.

What if we relax that assumption? Allocations may perturb other allocations -
that's how moving GC heaps work! Can that be modeled usefully in Rust?

~~~
amaranth
The allocator API hands out `*mut u8` so... not really. If you changed the
allocator API and everything that uses it and makes assumptions about how it
works then sure, you could make it hand out a pointer to a pointer so you
could come in later and update the inner pointer after you've done a GC pass.
You couldn't do something like handing out a normal `Box` and keeping track of
where it lives so you can patch it later though. Rust doesn't have move or
copy constructors so as it gets passed around it'll just be `memcpy`'d and
you'll lose track of it.

~~~
monadic2
I can’t imagine this utility will be replaced, either, as it’s the essence of
why rust works so well with the c abi. Augmented, hopefully?

------
fpoling
Chromium initial design was a very simple main process and few untrusted
relatively fat processes for web pages each holding set of tabs. That could
have worked with C++. However the need for site isolation, performance
considerations and hardware vulnerabilities later put an end to it.

For example, initially Chromium had no support from isolating iframes from the
main document. Everything was in Blink. But isolating iframes required
extremely complex code in the main process to properly forward all DOM events
between process. Then that code had to be made asynchronous so web pages could
not block main UI.

Then OS interfaces to GPU and it’s architecture rules out having GPU
accelerated graphics and decoders in a per-site process. So that must be put
in single a GPU process. Surely it is heavy sandboxed. But, as with the recent
Networking process, it is still a shared component with very complex C++ code
and fat platform libraries in C/Objective-C for interfacing with GPU.

So at the end the original idea of writing everything in C++ and using
sandboxed processes to make memory-safety bugs harmless just does not work.
One needs a memory-safe language.

The article mentioned various library-based approaches. But those, as having
such foreign C++ usage, are becoming essentially domain-specific-languages
that one needs to learn. That leads to boilerplating as the host language is
not well-suited for that.

~~~
blub
The idea of writing a constantly changing application and feeding it only
untrusted content over the network while exposing more and more of the OS to
that application does not work.

It doesn't work in Firefox with its small block of Rust code, doesn't work in
Chrome nor Safari. Because it's the dumbest fucking idea ever.

But sure, at this point we don't have anything to lose by rewriting it in
Rust/Swift/whatever.

~~~
asiachick
And that alternative is what? you run no software on your computer? Native
apps have way more access to your system then a webpage so I'm glad there are
100s or 1000s of web apps I can run rather then being forced to install native
apps to get the same functionality.

~~~
blub
AppStore / platform package manager.

Web apps are anyway nonsense both from a privacy (zero privacy) and security
PoV (single high-value target, foreign jurisdiction, crappy browsers,
byzantine tools, hopelessly overcomplicated architectures etc).

------
alfiedotwtf
Every time someone tells me something along the lines of "you don't need Rust,
just be a better programmer", I lookup CVEs for the projects they've worked on
and sure enough there's memory safety issues.

Just because you're a good driver doesn't mean you should forgo a seat belt!

------
m463
What if with "dangerous languages" like C you could turn off pointers, or make
only functional subroutines?

For instance, perl has this construct, to make your programs better:

a program foo.pl:

    
    
      $c = 1;
    

runs fine. Now turn on strict:

    
    
      use strict;
      $c = 1;
    

and

    
    
      $ perl ./foo.pl 
      Global symbol "$c" requires explicit package name at ./foo.pl line 2.
      Execution of ./foo.pl aborted due to compilation errors.
    

you must declare $c:

    
    
      my $c = 1;
    

the idea would be... write your program and you can opt-in to various
constructs.

NOTE: my first example didnt' work.

    
    
      use strict;
      $a = 1;
    

won't throw an error. Turns out the variables "$a" and "$b" are exempt from
"use strict;" ha. wow.

~~~
raverbashing
> What if with "dangerous languages" like C you could turn off pointers

You can't. C is a fundamentally defective language because it doesn't have the
"memory slice"/"array" construct.

Of course you can work around it, but if you eliminate pointers then you can't
do much with C. Heck you can't even print "Hello World" with it (well, ok,
_technically_ you can but not in the usual way).

~~~
daotoad
You could use MISRA guidelines for C.

[https://en.wikipedia.org/wiki/MISRA_C](https://en.wikipedia.org/wiki/MISRA_C)

~~~
raverbashing
They seems to be behind a paywall so I can't comment much on that

But still, I believe you can't do much with C if you "shut down" pointers
completely. Because strings are pointers in the end.

~~~
m463
maybe the parent changed the link? the link appears to be wikipedia :)

~~~
raverbashing
Yes, the wiki has some recommendations (and I remember the C++ JSF standard)
but if you follow the link to the actual document it seems to be behind a
paywall

------
blintz
It's funny how prescient "Eternal War in Memory" feels:
[https://people.eecs.berkeley.edu/~dawnsong/papers/Oakland13-...](https://people.eecs.berkeley.edu/~dawnsong/papers/Oakland13-SoK-
CR.pdf)

Of course, it's slightly dated, but a lot of the points feel truly 'eternal'.
All of the SoK papers from Oakland are good, but this one is great.

------
WalterBright
D has been steadily focusing on solving memory safety problems. It now has a
prototype ownership/borrowing system incorporated into the language.

~~~
eatonphil
C++ also has ownership/borrowing system (i.e. smart pointers) now though too,
right? I'm a fan of D but isn't the problem about 1) defaults (or even
required behavior) and 2) existence of libraries following good paradigms more
so than just support for static memory management?

------
mkj
To me it seems likely the percentage is even higher in other programs - a web
browser has a pretty complicated privacy/isolation model compared with most
other programs so that increases the 23.9% "Other" here. Normal "logic" bugs
would be more likely to have security implications.

------
mkj
What is the "//base" mentioned here? It's kinda hard to google...

"//base is already getting into shape for spatial memory safety"

~~~
maccam94
Chromium uses a build tool called bazel. //base is a bazel path, where // is
the root of a workspace (which is usually a version controlled repository).
Thus it is referring to
[https://chromium.googlesource.com/chromium/src/+/refs/heads/...](https://chromium.googlesource.com/chromium/src/+/refs/heads/master/base/)

~~~
onekorg
Chromium actually uses GN, not bazel.

[https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_P...](https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_PoIbbzQ3GQi_cpujYwbpcbZo/edit?usp=drivesdk)

~~~
maccam94
Oh interesting, TIL. The syntax looked similar and it's a Google project, so I
assumed gn was just some BUILD file generator on top.

------
jariel
Question to C++ pros: are there not idioms that can be used and ruthlessly
enforced to avoid such problems entirely?

Is this the result of 'open use of pointers' that inevitably causes problems
here and there?

Or is this problem due to the fact is just impossible to use even hard idioms
to avoid such problems? (Or hard to enforce them?)

On some small-to-midsized projects I've seen narrow and rigorously enforced
rules around pointers that seemed to work well. So what's up?

~~~
MaulingMonkey
> Question to C++ pros: are there not idioms that can be used and ruthlessly
> enforced to avoid such problems entirely?

"In theory, yes - in practice, no."

You can use static analysis, vendor-specific annotations, runtime tools like
clang's various sanitizers or valgrind, thorough code audits, use smart
pointers instead of raw, have clear ownership semantics, follow MIRSA C
guidelines, NASA guidelines, etc etc etc... but eventually your project will
grow to the point where you'll botch an edge case, and the number of botched
edge cases all your coworkers manage to add up will turn into a statistic.

Even if me and all my coworkers were all godlings incapable of making
mistakes, we'd _still_ end up debugging plenty of memory safety issues - in
second/third party code, sometimes without source code, and writing bug
reports / workarounds as a result.

~~~
jillesvangurp
Also, you can assume Google to be using all of the tools at their disposal.
The stakes are high for them and they've been dealing with security issues for
a long time. It helps, but it's obviously not enough. This seems to be true
for most widely used C/C++ code bases; including those with decades of
scrutiny. At best some projects have a good track record when it comes to
dealing with these issues in a diligent way. Chromium seems to be one of those
projects.

------
thePunisher
The biggest problem is we are using systems programming languages to develop
applications. We need to use application programming languages to develop
applications. C and C++ are systems programming languages, to be used for
developing operating systems, device drivers and other low level stuff.

The problem is, we haven't had a real application programming language since
the demise of Pascal / Delphi. And Java / C# have been able to pick-up some of
the slack, but not nearly enough as there are still tons of software being
written in unsafe languages.

~~~
miohtama
The browsers have become systems themselves. Browsers need GPU, IO, media,
etc. subsystems.

------
VSPrw3C1yK
Does Chromium test with valgrind, various sanitizers and static checkers?
Since when? This is 5 years of bugs. How many would be caught by modern tools?
Could those tools be improved to catch those bugs? I'm surprised this isn't
mentioned in what they're trying, but maybe they're at the practical limit.

------
hr0m
There is an proposal for a GC-library:
[https://docs.google.com/document/d/1Cv2IcsiokkGc2K_5FBTDKekN...](https://docs.google.com/document/d/1Cv2IcsiokkGc2K_5FBTDKekNzTn3iTEUyi9fDOud9wU/edit#heading=h.i5ibcxqde9h2)

That is just like programming in D with extra steps.

------
foobar_
Can't we just enable bounds checking and gc and live with slowness. Shouldn't
that be a choice, a compiler flag ?

Every time there is a security issue, someone can see your naked pictures.

~~~
GordonS
Do you know of any fully-featured Web browsers that have been implemented with
"safe" language, such as C# or Java? Would be a really interesting project to
see!

~~~
_ph_
Very early on, Sun had a web browser implemented in Java. Unfortunately, this
was dropped before Java got Hotspot and with that the decisive speed up. (They
also had a web server implemented in Java, which sounds like an excellent idea
too)

------
johndoe42377
Switching to a safe language is, obviously, not an option.

However, it is possible, especially with resources of Google and other C++
shops to develop an advanced lint, which could be just a ripoff of compile
time borrow checking from Rust (taking into account complexity of c++ memory
model).

Flagging simple things like use after free would already be a big deal.

Nowadays it probably should be a plugin for clang or something similar instead
of lint.

~~~
titzer
We should have more courage and attempt big things.

Like writing the program we already wrote....again.

We take this option off the table. Cannot rewrite. Definitely not in a safe
language! Surely we have ceased to dream?

~~~
adev_
> We should have more courage and attempt big things.

> Like writing the program we already wrote....again.

That's not named courage, that's named stupidity. Specially when the program
you talk about is several millions lines of code and the results of years en
engineering of entire teams.

> We take this option off the table. Cannot rewrite. Definitely not in a safe
> language! Surely we have ceased to dream?

There is people that dreams and there is the one that code.

Evolution are (almost) always preferrable to Revolution.

In this case, Evolution can mean:

\- Rewrite progressively the security sensible part in Rust mixed with the
legacy (aka the Mozilla way)

\- Develop the tooling to make C++ _safer_ / or even better _safe_. That has
already been done for a subset in the aeronautic industry

\- Work with the comitte to make C++ itself _safer_ , which Google is already
doing.

------
Yuioup
This is why C++ should be put to pasture and replaced by properly managed
languages. It's time.

~~~
cgrealy
Sure, all we need to do is rewrite billions of lines of code in some of the
most popular software on the planet.

And then replace it with... a language that is exactly as performant, is
available on every known platform and has replacements for all the existing
libraries (including all the ones written in C!).

~~~
titzer
I'll pay 15% performance for safety[1]. It's just that we have the wrong
priorities, and you betrayed that default attitude again with the requirement
that everything be "exactly as fast" as before. I still do not understand this
focus on performance above everything else. It is absolutely unquestioned. We
can't even talk about it. And it's constantly an argument that is undone by
time. Machines are _still_ getting faster. In the heydays of Moore's law, when
performance was doubling literally every 12 months, if we were arguing about
15% of CPU performance, that's 2-- _TWO_ \--months of performance. Now, it
might be 1-2 years to get 15% single-core performance. But almost no one is
limited by single-core performance anymore.

We got stuck with the worst of all possible worlds--long compile times, long
debugging times, long bugtails, horrible security, rickety and hard to
refactor, ugly code. Oh, but it's fast. Fast and broken. Wonderful. Wonderful.
Grandma is so much happier with her 15% faster something or other that spends
95% of its time idle waiting for user input. Oh, but that 15% of 5%...man that
0.8% is keeping me up at night! We forgot to zoom out to see that people need
and depend on reliable software and utterly failed at that. It's as if we
removed seatbelts, airbags, windshields, and mounted knives in random places
in cars because we thought everyone wanted to go fast. No other disciple in
all of engineering is so wrong with their priorities. God, society should be
hopping mad at us for being so hostile to them.

[1] Obviously, performance differences between "fast" languages and "safe"
languages are so variable that we might as well be talking about comparing
Fords to Ferraris--without specifying whether we are talking racecars (Ford
makes some fast ones)! But 15% is a number we see often in the JVM world.
After years in this field, I think the fastest safe language is not more than
15% off the fastest unsafe language, across the wide spectrum. Sometimes, you
can get absolutely the same performance for the innermost hot loop out of a
safe language vs unsafe language in some situations, you can get 2x slower.
But people get terrified they'll never figure out why, that there is some kind
of hidden, unknowable "language cost" they'll never get offer. Which is of
course hogwash. Every program can be tuned and improved. Offer tools to find
and remove bottlenecks and stop being sloppy with allocating memory.

~~~
cgrealy
I think you missed the main point, which was the "billions of lines of code"
part.

It's not a question of simply retiring C++.. it has to be replaced with
something. Even safe languages frequently rely on libraries implemented in C
or C++ as part of their runtime.

Even if you were willing to pay a 100% performance penalty (and there are
plenty of places where I'd be fine with that), it's still a massive
undertaking.

~~~
titzer
And usage of C++ is still growing exponentially, so the number of lines of
code is growing faster than our ability to rewrite/replace them. I know, it's
a losing battle. We'll never do it. We are stuck with C++ until the end of
time because of the sunk cost fallacy. If everyone who currently works on C++
instead switching to rewriting instead of adding, we'd be able to replace
everything in 5 years.

If C++ is only kept around because of a few libraries needed to implement the
runtime of safe languages, then I would consider that some kind of victory.

------
kerng
Hopefully Microsoft starts porting some of the code over to Rust soon. That
should help.

------
Animats
And that's new code, not legacy. Embarrassing. I would have expected better
from something written in this century. C++ does sort of have a safe subset.
If you're passing raw pointers all over the place today, you're doing it
wrong.

~~~
saagarjha
Anecdote: I had to track down a bug in one of my programs once because a
vexing parse caused the compiler to emit a call to the wrong specialization of
a constructor, leading to certain fields remaining uninitialized. This was in
a small, greenfield project that I wrote using the full force of modern C++17,
using the safest, most idiomatic constructs I could find. The fact that no
compiler or sanitizers made so much as a peep makes me feel that memory
unsafety is embedded so deep into the core of the language that extracting out
“the good parts” is probably of similar complexity to just detecting all the
problems ahead of time. (That is: impossible.)

~~~
Too
Not refuting that c++ can be made safe easily, but this particular error
should be blocked by clang-tidy. Assuming you use it and configured it
properly, picking the right analyzers is an equally witchcraft as writing
memory safe code in the first place. [https://clang.llvm.org/extra/clang-
tidy/checks/cppcoreguidel...](https://clang.llvm.org/extra/clang-
tidy/checks/cppcoreguidelines-pro-type-member-init.html)

~~~
saagarjha
I’m will have to admit that I haven’t tried clang-tidy on it (I will once I
get back to a computer), but I am unsure that it would be able to diagnose the
issue. I linked to the code in another comment
([https://news.ycombinator.com/item?id=23289614](https://news.ycombinator.com/item?id=23289614))
but the issue was that I have multiple template specializations of a class,
each of which has a constructor that fully initializes that specific
specialization’s members. The specific problem was that I used parentheses in
a context where I was letting the language deduce which constructor it needed
to call based on template arguments but (as far as I understand) this made it
deduce the type incorrectly and always call the unspecialized version that had
none of the members, but the type system let me coerce that into one of the
specialized ones (also not sure how, but presumably some magic along the lines
of “they were the same class”) and the non-shared members at that point were
not initialized. Oh, and this was in a constexpr context which essentially
generated a switch statement on an instruction opcode at compile time. So I’m
not confident that an automated tool could pick this up, although if when I
try it it finds the issue I will be _extremely_ impressed.

------
pmarreck
Would immutable variables (or as they call them in functional langs, just
“values”) ameliorate this problem?

~~~
frou_dh
That's just begging for completion of the circle with "or as they call them in
maths, variables" :)

------
phillipcarter
Why haven't they just started to rewrite it in rust yet?

~~~
pjmlp
Indeed, however Google's usage of C and C++ sometimes is quite interesting.

For example, Android source code is also not a very good example of modern
usage of C++ security features.

After 10 years, the NDK keeps having a C only API space, with all the memory
corruption issues that it entails, even though the actual implementations are
in C++ or Java (via JNI).

So their workaround, starting with Android 11, is requiring hardware memory
tagging in all ARM devices, while having kernel fuzzing support for other
platforms lacking such hardware capabilities.

~~~
gmueckl
The C only interface is an absolute necessity. Only C++ can properly interface
with C++ while C can interface with the rest of the world. And system
libraries are there for whole world to use. if the system interfaces were
converted to C++, all applications need to be written in C++ as well. You can
wrap some features in other languages, but definitely not all of them.

~~~
pjmlp
Right, but in 10 years they surely would have the time to offer a type safe
C++ API in addition, just like in other platforms.

Instead, they have been postponing it since NDK was introduced in Android 2.0
until after the introduction of native packages, which will only arrive with
Android 11.

There are open tickets related to it.

------
The_rationalist
They should contribute and use [https://herbsutter.com/2018/09/20/lifetime-
profile-v1-0-post...](https://herbsutter.com/2018/09/20/lifetime-
profile-v1-0-posted/)

------
rurban
That's why in the early 90ies people stepped back and created Java. Lisp was
in its AI winter, but memory safety was still top priority for the industry.

------
rb808
I gave up C++ 10 years ago and switched to more modern languages. I figured
the language would die off, so am a bit shocked its still so prevalent. I
really dont think there is any reason to use C or C++ any more, except perhaps
some low level layer that interacts with the hardware.

~~~
dmortin
Even if C++ is used less than before it won't die off and C++ experts can
demand more money especially because there are fewer of them as most
programmers move to more modern languages.

~~~
lsofzz
COBOL

~~~
dmortin
Yep, the same case. Only I read that those old COBOL programs are a huge mess
of spaghetti code, so you are well paid, but you have to put up with ugly,
hard to maintain code.

I'd rather work on something nicer for less money.

------
idoby
Not at all surprising, but it's not like Rust (and others like it) are going
to be a silver bullet against this. Any complex enough program running on a
stored-program computer (where code is data and data is code) will be
vulnerable.

You can reduce the attack surface, but never eliminate it.

~~~
95th
Yes. But at least 70% bugs will be gone

------
sumanthvepa
C++ can be used safely without memory safety issues. But it requires expertise
with the language, which is a very steep barrier for most programmers, even
ones on the Chrome team to pass successfully. In a project as large as Chrome
the vast majority of programmers will not have the necessary expertise. And
sadly, in this case, what you don't know will hurt you. Is that a reason for
not using C++: maybe. But you would be hard pressed to find a more performant
language that is mature and stable.

~~~
nindalf
We need to let go of this idea that there are godlike engineers out there who
can write perfect code. Everyone makes mistakes. As long as the compiler
allows it, such mistakes will continue to happen.

> in a project as large as Chrome the vast majority of programmers will not
> have the necessary expertise.

Then how do we staff such projects? Hire only people with a track record of
never writing such bugs? It’s not possible.

