[HN Gopher] Memory Safe Languages in Android 13
___________________________________________________________________
 
Memory Safe Languages in Android 13
 
Author : brundolf
Score  : 326 points
Date   : 2022-12-01 17:39 UTC (5 hours ago)
 
web link (security.googleblog.com)
w3m dump (security.googleblog.com)
 
| mk89 wrote:
| I am not a Rust or C++ fanboy, and I am happy that we are moving
| towards a future where there are less memory bugs, but... are we
| really?
| 
| - https://www.infoq.com/news/2021/11/rudra-rust-safety/
| 
| - https://cve.report/vendor/rust-lang
| 
| And you can find online similar links and research on the topic.
| 
| All it takes is that you use that specific piece of code at the
| wrong time, and that's it: your system which you once believed to
| be safe is not anymore safe. And you know what? You don't even
| know what a sanitizer is, because they told you that Rust is a
| memory safe language and you don't need anything else than the
| rust compiler - this is how I find 99% of today's articles about
| Rust.
| 
| Sure, today being Rust less used than C/C++ will clearly show
| less CVEs.
| 
| The question is ... once it's in the wild (and by this I mean
| "major" libs or serious shit done in Rust) how can you prevent
| such bugs without a runtime sanitizer?
| 
| Beware that such CVEs can affect Rust Standard library as well,
| not just an unknown library.
| 
| Again, there is no way of escaping bad programming and bad
| practices, no matter which language you use. Someone might argue
| that in Python or Java you can still do bad stuff, however, the
| likelihood is way lower, especially because most of your Java
| libraries will very likely be written in Java - unless you know
| it's using JNI under the hood etc.
 
  | IshKebab wrote:
  | Did you read this bit?
  | 
  | > It could appear that these results undermine the belief that
  | Rust safety model represents an improvement over other
  | languages, e.g. C++, but this would not be correct, say the
  | researchers behind Rudra, who still consider Rust safety a
  | supreme improvement.
  | 
  | They found ~100 security issues in 45k packages. That's clearly
  | better than C++.
 
    | mk89 wrote:
    | I didn't say it's not an improvement. I just wonder who will
    | you blame once you have a hacker exploiting that exact CVE
    | which you didn't know about because they sold you rust as
    | memory safe language, so you didn't take the time to run any
    | sanitizer or similar.
    | 
    | Does Rust provide a way to check if you're using unsafe code?
    | What if I want to disable that? If I need to make a mission
    | critical software I need to be aware of what I am deploying.
    | If on the other hand we want Rust to be the new JS for
    | backend, then yes so be it, we improved over c++, well done.
 
      | bluGill wrote:
      | Rust would have prevented about half of the CVEs in C code
      | (I've seen a few different studies with somewhat different
      | results, half is close enough for discussion). The other
      | half is on you to write good code.
      | 
      | Note that the half Rust would prevent tends to be less
      | impactful, still a CVE, but the exploit is less impactful
      | to end users.
 
        | mk89 wrote:
        | If we leave it to the programmer, what are we improving?
        | 
        | We did a big improvement, but why can't we disable
        | "unsafe"?
        | 
        | That would leave absolutely no margin for such errors.
 
        | masklinn wrote:
        | > We did a big improvement, but why can't we disable
        | "unsafe"?
        | 
        | Because there are things which literally can not be safe,
        | and rust will not let you get away with pretending.
 
        | throwup wrote:
        | Rust has a culture where people don't use `unsafe` unless
        | absolutely necessary. That is generally good enough in my
        | experience.
        | 
        | If you want to go further, you can disable unsafe in a
        | crate by adding #[forbid(unsafe)].
        | 
        | And if you need more control than that, there's probably
        | tooling out there that will help depending on what
        | exactly you need.
        | 
        | https://github.com/rustsec/rustsec/tree/main/cargo-audit
        | 
        | https://github.com/rust-secure-code/cargo-geiger
        | 
        | https://github.com/crev-dev/cargo-crev
 
      | stouset wrote:
      | > I didn't say it's not an improvement.
      | 
      | You... almost literally did?
      | 
      | > I am happy that we are moving towards a future where
      | there are less memory bugs, but... are we really?
 
  | fiedzia wrote:
  | > they told you that Rust is a memory safe language and you
  | don't need anything else than the rust compiler - this is how I
  | find 99% of today's articles about Rust.
  | 
  | It is - as long as you don't use unsafe. Which is very rare, so
  | we've made huge progress here already. Validation for cases
  | where unsafe is necessary is needed and welcomed, but doesn't
  | change the fact that 99% safe Rust is much better than 100%
  | unsafe C/C++.
  | 
  | > Again, there is no way of escaping bad programming and bad
  | practices, no matter which language you use.
  | 
  | Escape entirely maybe not. Eliminate most of it - definitely.
 
  | joshuamorton wrote:
  | Yes.
  | 
  | They found 250 bugs after analyzing the entirety of rust and
  | all of it's packages.
  | 
  | There are probably more memory safety bugs in the python
  | standard library and top 50k packages.
 
    | masklinn wrote:
    | The rust project itself also has an extremely aggressive CVE
    | policy (which many find too aggressive): if unsoundness is
    | found in an API it gets a CVE, no matter how convoluted, and
    | how unlikely it is to get into that situation, with
    | absolutely no guarantee of any code in the wild coming even
    | close to the unsoundness.
    | 
    | Essentially, the Rust standard is that more or less every
    | line of the C++ standard is a CVE.
    | 
    | Hell, the Rust project releases CVE for things other
    | languages literally just shrug about e.g. https://blog.rust-
    | lang.org/2022/01/20/cve-2022-21658.html
    | 
    | The C++ people just go "lol nothing in std::filesystem is
    | safe we don't give a shit". The spec pretty much says it's UB
    | to have other programs interact with the filesystem:
    | http://eel.is/c++draft/fs.race.behavior#1.sentence-2
 
      | [deleted]
 
      | steveklabnik wrote:
      | Many CVEs in the Rust ecosystem aren't filed by the Rust
      | project itself. Anyone can file a CVE, it does not require
      | involvement of upstream.
      | 
      | That said things that happen in the language or standard
      | libraries like the one you linked, are often (but not
      | always!) filed by the project.
 
| cryptonector wrote:
| > Safety measures make memory-unsafe languages slow > > Mobile
| devices have limited resources and we're always trying to make
| better use of them to provide users with a better experience (for
| example, by optimizing performance, improving battery life, and
| reducing lag). Using memory unsafe code often means that we have
| to make tradeoffs between security and performance, such as
| adding additional sandboxing, sanitizers, runtime mitigations,
| and hardware protections. Unfortunately, these all negatively
| impact code size, memory, and performance.
| 
| Even more evidence that the negative performance impact of bounds
| checking is minimal, nay, it can even be positive.
 
  | kllrnohj wrote:
  | No it isn't. It's just evidence that it's a trade-off you might
  | want to make in order to achieve some other goal, specifically
  | security.
  | 
  | But if "security" isn't remotely a concern for a given project
  | (like almost anything graphics / gaming related), this is not
  | at all evidence for changing anything. It _could_ be that Rust
  | 's optimizer eliminates the bounds checking so regularly as to
  | be a moot point, but _this_ isn 't saying anything of the sort.
  | It's saying that the cost, whatever it was, was judged to be
  | worth paying for the improved security _for these projects_
 
    | masklinn wrote:
    | > But if "security" isn't remotely a concern for a given
    | project (like almost anything graphics / gaming related)
    | 
    | Gaming platforms have gotten a lot less lenient over time,
    | and with pretty much every game these days having online
    | components, "security isn't remotely a concern" has become a
    | lot less true.
 
      | berkut wrote:
      | Sure, but then there's things like HPC / offline graphics /
      | simulation (VFX/CG), where performance is the end-all
      | concern (or memory efficiency sometimes at the expense of
      | CPU time), and security isn't a concern at all there, with
      | lots of things like random index lookups into sparse arrays
      | / grids, etc. I know for a fact that bound checks do make a
      | bit of a difference there, as the data's random, so the
      | branch predictors are close to useless in that situation...
 
        | lynndotpy wrote:
        | Security is absolutely a concern in these areas (except
        | maybe offline graphics).
        | 
        | In my experiences with university HPC clusters, security
        | is very important because you have a lot of young
        | students with no Unix experience accessing the resources.
        | We've had real compromises of individual research
        | machines because of this.
        | 
        | This happens all the time at research universities, but
        | it's not always public. In one public example from my
        | uni, hackers from China compromised a research machine,
        | which was used to attack IT infrastructure, which lead to
        | PII including SSNs being compromised.
 
        | berkut wrote:
        | That's security of the generic infrastructure the code's
        | running under though is it not? It's not security of say
        | CUDA kernel code being executed on a GPU?
        | 
        | I'm talking about the actual HPC algorithm code _heavily_
        | priortising performance (or in some cases memory
        | efficiency), at the expense of pretty much everything
        | else (other than correctness, obviously).
 
        | Ar-Curunir wrote:
        | If your high performance code running on a sensitive
        | cluster is vulnerable, then it opens up the rest of the
        | system to exploitation also. How is it a problem of the
        | infrastructure around the code, and not the code itself?
 
        | yosefk wrote:
        | Everybody who works with Maya, Flash (now Adobe Animate)
        | etc. knows that they crash all the time, and often
        | corrupt files so you back them up every hour or so.
        | Carmack insists, in a gaming context, to run heavyweight,
        | high-false-positive-rate static analyzers because users
        | don't like crashes.
        | 
        | When C++ dies (which in 20 years it will, and I wasn't
        | that hopeful 20 years ago), people will look in the same
        | bewilderment at excuses made for its insane behavior as
        | they look now at mid-20th-century arguments against high-
        | level languages (and assemblers before them - like Mel
        | said, "you never know where it will put things so you'd
        | have to use separate constants.")
 
        | Taywee wrote:
        | > which in 20 years it will, and I wasn't that hopeful 20
        | years ago
        | 
        | That's too optimistic. C++ would easily die in 20 years
        | if it didn't already have 30+ years of still-active
        | legacy that can't easily be converted or rewritten.
        | 
        | I've recently even had to start new projects in C++
        | because platforms I depend on demand it or because I have
        | to interface with existing code and libraries that still
        | only exist as C++. I'm not a fan of the language by any
        | means, but I'll eat my shoe if it's "dead" in 20 years
        | for anything except maybe greenfield development.
 
        | yosefk wrote:
        | Dead - no, dying COBOL-style - quite possibly.
 
        | berkut wrote:
        | At least in VFX, at the high-end Maya's only really used
        | for modelling/UVing/layout now, other apps have taken
        | over the rendering/lighting side of things...
        | 
        | But anyway, in my experience a lot of the crashes are
        | often due to quickly hacked together plugins for the
        | various DCCs written for artists, that don't have good
        | error checking or testing, and it's not completely clear
        | to me how that situation's going to improve that much
        | with something like Rust, if the same programmer time
        | constraints are going to exist in writing them: i.e. I
        | think it's very likely people will just unwrap() their
        | way to getting things to compile instead of correctly
        | handling errors, so it will be the same situation from
        | the artists' perspective: technically it may be a panic
        | rather than a segfault, but from the artists'
        | perspective, it will likely be identical and take the DCC
        | down.
 
        | estebank wrote:
        | panics can be caught and the presence of those unwraps
        | come with enough data that filing a bug report upstream
        | is helpful enough to fix the bug.
 
        | berkut wrote:
        | Sure, but that (we do it) happens currently with C/C++
        | and signal handler traps which gather the callstack and
        | collate them: the issue isn't usually that we don't know
        | the crashes aren't happening or having the call stacks -
        | the issue is hacky code that was written for one purpose
        | is now being used for other things it wasn't designed for
        | (because it is useful to artists, despite its
        | limitations), and there isn't the time to go back and
        | write it properly for the new expanded use-case. That's
        | my point: a new safer language isn't going to improve
        | much in this area without more development time provided
        | to write better code, given the time constraints are
        | going to be the same as they are currently.
 
        | estebank wrote:
        | It does change the situation if the plugin throws an
        | exception on errors instead of causing a segfault that
        | brings down the parent application.
 
    | estebank wrote:
    | It's not just about bounds checks. I am way more agressive
    | about borrowing fields of other types, particularly mutable
    | borrows in ways that I wouldn't attempt in C to protect
    | myself from future code from breaking invariants I'd have to
    | rely on. This means I can write the hyper optimized version
    | of an algorithm on any language, but I'm more likely to even
    | attempt it in Rust.
 
      | masklinn wrote:
      | An other bit I first saw observed by Armin Ronacher and
      | which is indeed quite common is that Rust does not require
      | you to be defensive (and pay the price) around protected
      | resources e.g. you can hand out references to rc'd types
      | (avoiding refcount traffic) or mutex'd, and you know it's
      | safe, if a bit constraining.
 
    | bluGill wrote:
    | I take it the opposite: C programmers out of abundance of
    | caution of putting in bounds checks for code that will never
    | be called with out of bound data. As such rust is eliminating
    | code that is being manually written. If you don't write the
    | bounds check in C, and rust for the equivalent determines
    | that the bounds check isn't needed the code should be the
    | same (to the assembly level). However if you write a bounds
    | check in C the optimizer might not eliminate it.
 
      | kllrnohj wrote:
      | Can you point to any such bounds check in C that an
      | optimizer cannot eliminate but it can eliminate the
      | equivalent one in Rust?
      | 
      | I'm sure it's possible to construct such a thing, but I
      | cannot imagine it ever being common enough to show up on
      | any sort of head to head comparison.
 
        | tialaramex wrote:
        | I would guess all the aliasing stuff will get you. In C
        | it's very difficult for the compiler to know whether two
        | pointers are aliased, if we change X maybe Y changes too
        | (because actually X and Y were the same). In Rust if we
        | can _write_ to it then it isn 't aliased, and if we can't
        | write to it then nobody can change it, thus changing X
        | definitely can't change Y and the emitted machine code is
        | sometimes simpler as a result, doing what you naively
        | expected rather than what the C needs to do just in case
        | you're crazy and there is an alias.
        | 
        | Now, in modern C you can _say_ you don 't have aliasing,
        | but you're probably wrong and so there's a high risk when
        | you do that you now get "impossible" bugs because you
        | swore to the optimiser that if X changes, Y is
        | unaffected, then created a situation where that wasn't
        | true and now your program has no defined meaning, which
        | is going to be tricky to debug. So, on the whole C
        | programmers do not use this, indeed in places like the
        | Linux kernel they even turn off the C standard's very
        | minimal aliasing rules (which forbid aliasing objects of
        | different types), they just don't trust themselves.
 
        | kllrnohj wrote:
        | But the compiler doesn't need to care in that case
        | because it's not bounds checking those pointers in the
        | first place in C. So that's not going to give you slow C
        | code from bounds checking that the optimizer failed to
        | eliminate.
        | 
        | Like yeah there's aliasing changes, but in "idiomatic"
        | C/C++ how is that getting you bounds checking that's not
        | being optimized away fairly consistently?
 
        | Gankra wrote:
        | there's almost no bounds checking in rust code before the
        | optimizer even looks at it because we use iterators and
        | not goofy manually indexed for loops that are begging you
        | to make a typo that crashes your code :)
 
        | kllrnohj wrote:
        | Yeah but idiomatic modern C++ is also using iterators and
        | even before that there's no bounds checking to eliminate
        | in the first place since operator[] is unchecked so the
        | optimizer can't be struggling to eliminate it since it's
        | not there.
        | 
        | The question isn't "does Rust have bad bounds checking
        | optimizations" but rather "what is this mythical heavily-
        | bounds-checked C code that the compiler can't optimize
        | away?"
 
        | Gankra wrote:
        | No the claim is always that Rust "must" be slower than
        | C/C++ because it has pervasive bounds checking for array
        | indexing.
        | 
        | Then people insist on wanting to replace every x[i] in
        | prod with x.get_unchecked(i) only to learn that, not only
        | was that indexing not slowing the code down (the branch
        | is perfectly predictable in a correct program!), but
        | actually any difference is so in the noise that the
        | random perturbation is worse (or that the asserts were
        | actually adding extra facts for more profitable
        | optimizations in llvm).
        | 
        | There is definitely specific hot loops with weird access
        | patterns where it can be high impact but those are the
        | exception, not the rule, as the Android team
        | demonstrated.
 
        | stouset wrote:
        | Trivially, anything using the Iterator trait.
        | 
        | I don't know that I've _ever_ actually manually indexed
        | an array over years of using Rust.
 
        | berkut wrote:
        | In the HPC / offline graphics / simulation world, there's
        | lots of things like sparse arrays / grids, where you
        | index into compacted grids and iterators wouldn't be that
        | practical in that scenario (i.e. one single item,
        | although for things like filtering with surrounding cells
        | they can still be useful sometimes), and bounds checks do
        | make a bit of a difference there (it's definitely
        | measureable above the noise threshold), and due to the
        | random nature of the data, the branch predictors don't
        | help avoid the overhead.
 
        | stouset wrote:
        | Sure, I know there's paradigms where manual indexing is
        | important. GP asked for an example where bounds-checking
        | could be eliminated in Rust, so I gave the first one I
        | thought of.
 
        | kllrnohj wrote:
        | I don't think your answer is relevant to the question:
        | 
        | > Can you point to any such bounds check in C
 
  | bluGill wrote:
  | I wonder how much of the positive performance is just because
  | we have not proved that some impossible case is really
  | impossible and so we have if statements checking for a
  | situation that mathematically cannot happen just out of
  | caution. (note that in many cases we don't even have the
  | theoretical tools to prove the code)
  | 
  | Though that makes non-memory safe code more reliable in the
  | case of a bit flip. (this is not a serious advantage - only
  | some bit flips can be prevented this way)
 
| mark_l_watson wrote:
| How does Swift compare to Rust in safety? I read that Swift is
| only memory safe in single threaded environments, which is not
| ideal.
| 
| I was very enthusiastic about Rust about 4 years ago but decided
| to learn Swift instead as a new "cool non-Lisp language" to
| learn. Seeing an recent article on writing Python in Rust made me
| wish that I had chosen differently.
| 
| I found this article made me feel better about security. I expect
| that increasing use of memory safe languages will lock down
| public infrastructure and software, making everyone safer.
 
| blub wrote:
| No such luck in having some technical discussion or at least a
| link to the sources.
| 
| If the Rust community can be insufferable when trying to sell
| Rust at any and every opportunity, Lord have mercy when they see
| any kind of success because the preening and puffing will have no
| end. This blog post will live forever in the annals of Rust.
| 
| On the other hand I'm not surprised to see that it's written by
| the security team and not a development team. Same pattern as
| with Microsoft: security specialists tend to get obsessed by
| their subject matter (just like many Rust programmers), end up
| hating C and C++ and see them as the source of all problems (just
| like many Rust programmers).
| 
| In reality, C and C++ were the saviors of Android and Google
| reluctantly had to conjure the NDK to make up for a severe lack
| of performance compared to the iPhone. Note how even in the
| current Android they mention improving the UI performance and
| having less "jank". Without C++ Android would have been DoA, but
| it doesn't look like there will be a blog post thanking C++ any
| time soon :-)
| 
| I can't take seriously reports about the benefits of a tool that
| don't mention any of the downsides. When the devs post a blog
| cursing the troubles they had getting Java and C++ and Rust to
| work together and pitying themselves for having to read both C++
| and Rust, then we'll be getting closer to the truth.
 
  | Ar-Curunir wrote:
  | Yes, C++ was critical to Android in the past, when there was no
  | memory-safe low level systems language that could provide an
  | alternative. Now there is, so they're using it, and finding
  | benefits, and writing about those benefits.
  | 
  | What should they do instead, write an eulogy to C++?
 
| goodpoint wrote:
| I'll be downvoted for pointing out that comparing C++ with Rust
| without further context can be made into a false dichotomy.
| 
| Some people are posting the article around the Internet as
| evidence that Rust solved security. Instead, there are many other
| memory safe languages around and there has been thousands in the
| past. Additionally, many security issues are not due to memory
| safety. Please keep that in mind when making comparisons.
| 
| EDIT: of course, 2 minutes and I'm downvoted down to -2
 
  | insanitybit wrote:
  | You're being downvoted because your points are directly
  | addressed and refuted with evidence in the article. They
  | explicitly address different vulnerability classes.
 
  | burntsushi wrote:
  | Can you link to _anyone_ with any modicum of credibility
  | declaring that this article is evidence that  "Rust solved
  | security"? I'll be the first to point out that memory safety
  | related vulnerabilities are merely a subset (albeit a big one)
  | of all possible vulnerabilities.
 
    | goodpoint wrote:
    | That's what I wrote.
 
      | burntsushi wrote:
      | ... yes? And I'm asking you, who is saying that? _You_
      | said:
      | 
      | > Some people are posting the article around the Internet
      | as evidence that Rust solved security.
      | 
      | OK, so show me. Let's see all these people declaring that
      | this is "evidence that Rust solved security."
      | 
      | I think it's far more likely that you're exaggerating what
      | folks are saying to make them appear far more unreasonable
      | than they actually are. But we can't know that unless you
      | actually show your work, now can we?
 
  | est31 wrote:
  | > there are many other memory safe languages around and there
  | has been thousands in the past.
  | 
  | Yes, and in fact they write about how they are replacing C/C++
  | with Kotlin or Java. All three are memory safe languages. But
  | Rust is the only low level language of the three. This is
  | Rust's killer feature. Of course, JavaScript is memory safe and
  | so is Lua. But they are high level languages.
  | 
  | > Additionally, many security issues are not due to memory
  | safety.
  | 
  | I think it depends on the domain the program is in. If you are
  | a program managing some security property, like e.g. TLS
  | encryption, then virtually any bug you have might be a security
  | issue. Same goes for OS kernels. But if you are e.g. an image
  | decoder library, then there is little security impact if your
  | output is a weirdly colored image. But memory safety issues
  | might still be a problem for your decoder library.
  | 
  | Overall the number being cited is 70/30, as in, 70% of security
  | issues are memory safety ones, and 30% are ones which are not
  | about memory safety.
  | 
  | https://www.zdnet.com/article/microsoft-70-percent-of-all-se...
  | 
  | So you can reduce the number of security issues by 70%, isn't
  | that great?
 
  | bmicraft wrote:
  | It really sounds like you didn't read the article at all. It
  | explicitly mentions Java/Kotlin in one breath with rust almost
  | any chance it gets.
 
  | PoignardAzur wrote:
  | Preemptively complaining about downvotes is a great way to get
  | downvotes.
  | 
  | That doesn't make you a martyr.
 
  | kangalioo wrote:
  | But I think other memory safe languages don't have C++-like
  | performance, right?
 
    | goodpoint wrote:
    | There's been many, for example Ada/SPARK, D, Nim, Java,
    | Kotlin, Swift.
 
      | kllrnohj wrote:
      | I can't speak to the others, but Java & Kotlin do not at
      | all have C++-like performance, especially not in anything
      | beyond a toy level benchmark.
      | 
      | And even in those toy level benchmarks (like
      | https://benchmarksgame-
      | team.pages.debian.net/benchmarksgame/... ), there's a clear
      | divide between C/C++/Rust & everything else.
 
        | goodpoint wrote:
        | The claim that performance are comparable only on "toy
        | benchmarks" is false. Additionally, most of such simple
        | benchmarks are not representative for real-life workload,
        | and anyways the initial point was about safety.
        | 
        | Anyhow the whole HN conversation is now a trainwreck
        | where any dissenting opinion is downvoted so there's no
        | point to continue.
 
      | nneonneo wrote:
      | - Ada: good example, has substantial uses in certain areas.
      | However, certain things are quite difficult, e.g. compile-
      | time checked pointers (a la Rust's borrow-checked
      | references).
      | 
      | - D, Nim: neither provide strong memory safety guarantees.
      | D has a safe subset, but it's not default (see
      | https://news.ycombinator.com/item?id=12391720). Nim allows
      | you to turn checks off at runtime. Both Nim and D generally
      | use a GC.
      | 
      | - Java/Kotlin are not low-level: requires GC, and not often
      | used for low-level systems programming. Great languages,
      | but different niche.
 
        | thesuperbigfrog wrote:
        | >> Ada: good example, but not usually used for low-level
        | systems programming. Has substantial uses in certain
        | areas.
        | 
        | Ada is _primarily_ used for low-level systems programming
        | and embedded systems:
        | 
        | https://learn.adacore.com/courses/intro-to-
        | ada/chapters/intr...
        | 
        | Substantial portions of the Ada standard deal with
        | systems programming and low-level representation on
        | hardware:
        | 
        | http://www.ada-auth.org/standards/22rm/html/RM-C.html
        | 
        | http://www.ada-auth.org/standards/22rm/html/RM-13-1.html
 
        | nneonneo wrote:
        | Thanks for the correction. I will update my comment
        | accordingly.
 
  | nequo wrote:
  | This seems like a straw man. Who said that Rust is the only
  | memory-safe language? The title of the post itself uses
  | "languages" in plural.
 
| modshatereality wrote:
| is this a good way to spend developer time? How about *removing*
| all of the middle-man bloatware instead of wasting how many dev-
| years rewriting it (edit: and effectively making it even LESS
| maintainable now that it's in some new niche language with a
| vastly smaller dev pool). just give me the direct linux
| experience we all deserve instead of this garbo spamflinger
| middlewear that google leverages to keep you dependent on their
| build methodology and discourage cooperation with other
| competitive linux-based system.
| 
| edit2: wow mods hard at work, already removed one dissenting
| post.
 
  | bmicraft wrote:
  | > and effectively making it even LESS maintainable now that
  | it's in some new niche language with a vastly smaller dev pool
  | 
  | How is any language supposed to grow if you're only allowed to
  | use it once everybody does? Somebody has to be first (and
  | google isn't, not by a long shot)
 
    | modshatereality wrote:
    | You should at least wait until there is more than one
    | working/usable compiler for the language if you're going to
    | start making systemic changes to your multi-billion-dollar
    | code base responsible for the commerce of multiple billions
    | of people on the planet. It's a weird move at this point for
    | google to be making(edit: considering go is already supported
    | on multiple compilers).
 
      | insanitybit wrote:
      | "It should have two compilers" is a pretty arbitrary
      | benchmark for production readiness. I'd suggest the
      | benchmark be based on, idk, something with any fucking
      | meaning.
 
        | modshatereality wrote:
        | >something with any fucking meaning
        | 
        | So you claim to have a better metric, feel free to share
        | it?
        | 
        | site broken and wont let me reply any more: "shipped into
        | production" is meaningless, compilers are directly
        | related to language community and complexity.
 
        | insanitybit wrote:
        | How about numerous companies shipping Rust to production
        | for years? That metric is actually related to risk with
        | regards to shipping rust in production, unlike number of
        | compilers, which signifies nothing.
 
| binkHN wrote:
| From the bottom of the article:
| 
| > As Android migrates away from C/C++ to Java/Kotlin/Rust, we
| expect the number of memory safety vulnerabilities to continue to
| fall. Here's to a future where memory corruption bugs on Android
| are rare!
 
  | lzooz wrote:
  | How about speed from going from C/C++ to Java/Kotlin? Have they
  | considered that even?
 
    | summerlight wrote:
    | It will most likely be C/C++ -> Rust for performance critical
    | modules.
 
    | HideousKojima wrote:
    | I'm assuming that's why they have Rust in the mix there, for
    | where performance is still critical.
 
    | insanitybit wrote:
    | See the section "Safety measures make memory-unsafe languages
    | slow"
 
| latenightcoding wrote:
| I wonder if their efforts to leverage modern chip capabilities to
| address memory safety (e.g: ARM memory tagging) contributed to
| that drop of memory safety vulnerabilities
 
| GuB-42 wrote:
| I didn't realize there was so much C and C++ in Android, I
| thought most of it was Java. Maybe they are just talking about
| the core system (including the Linux kernel and Java runtime) and
| not all the builtin apps.
 
  | kllrnohj wrote:
  | Much of the graphics, camera, media, bluetooth, wifi, input
  | handling, etc... stacks are native. There's a massive amount of
  | native code in Android below the veneer of the Java API that
  | apps are given.
  | 
  | Many of the higher level constructs are then in Java/Kotlin,
  | though, like the builtin apps, system ui, activity & window
  | managers, etc...
 
| Octokiddie wrote:
| > This matches the expectations published in our blog post 2
| years ago about the age of memory safety vulnerabilities and why
| our focus should be on new code, not rewriting existing
| components.
| 
| and
| 
| > As we noted in the original announcement, our goal is not to
| convert existing C/C++ to Rust, but rather to shift development
| of new code to memory safe languages over time.
| 
| For those working on C/C++ code bases, how does the incremental
| addition of Rust work in practice? What strategies and tools come
| in handy? Also, what are some good case studies where Rust was
| introduced to add new features, but still needed to work within a
| system mainly composed of C/C++? I've seen some of the first
| steps with Linux, but I'm thinking of a project where more
| substantial additions have been made.
 
  | antonok wrote:
  | Brave Browser has some Rust components too (e.g. the adblocking
  | engine). Rust in C++ works very well for components with a
  | small, well-defined API surface that involve a lot of logic.
  | You only need to build a small FFI layer for the direct
  | interfaces between the two languages. CXX [1] makes this even
  | easier, too.
  | 
  | Brave is definitely _not_ aiming to convert the entire browser
  | to Rust, but it 's increasingly chosen for new development.
  | 
  | [1] https://cxx.rs/
 
  | halpmeh wrote:
  | I imagine it works just like FFI works in other languages.
  | Compile a c-archive and link against it.
 
  | bluGill wrote:
  | I've only started scratching the surface, but that rust really
  | wants you to use Cargo, while we have our own homegrown package
  | manager, and cmake creates a lot of friction.
  | 
  | I can tell you that bad programmers can write bad code in Rust.
 
    | TheNorthman wrote:
    | > I can tell you that bad programmers can write bad code in
    | Rust.
    | 
    | Of course. The question rust users seem to put forth is that
    | bad programmers write _better_ (not good) rust code than C
    | code.
    | 
    | That bad programmers write bad code is to expected. That is,
    | after all, a likely explanation for why they're bad.
 
      | nneonneo wrote:
      | I would argue that the type system does make it somewhat
      | more difficult for bad programmers to do egregiously bad
      | things in the language. A carefully written library can be
      | quite difficult to misuse (at least, without panics or
      | using unsafe code in the user code, both of which are easy
      | to catch in code review).
      | 
      | Rust has no null/nil pointers. Instead, it has nullable
      | types (Option), which are harder to misuse. If you want
      | to "dereference" a Option, you either use unwrap() (which
      | panics) or you handle the None case properly. While
      | `.unwrap().foo()` is still just as crashy as an unguarded
      | `x->foo()` in other languages, a code review can catch
      | misuse of .unwrap() much more readily than a missing
      | null/nil check.
      | 
      | As another example, the Send/Sync traits provide strong
      | guarantees about thread safety; using these traits properly
      | lets you make data structures that cannot be misused in a
      | multithreaded program. Although deadlock is still possible
      | (hello, halting problem), many types of data races are
      | simply eliminated.
 
        | optionalsquid wrote:
        | > While `.unwrap().foo()` is still just as crashy as an
        | unguarded `x->foo()` in other languages
        | 
        | I think it is also worth noting that unwrap itself is
        | much safer than an unguarded `x->foo()`, since it doesn't
        | involve undefined behavior. Meanwhile an unguarded
        | `x->foo()` allows compiler to assume that x is never null
        | and consequently do things that the programmer wouldn't
        | expect. The recent post on undefined behavior [1] had a
        | (to me) quite shocking example of that [2]. So while bad
        | Rust programmers misusing unwrap get crashes, they won't
        | get nasal demons.
        | 
        | [1] https://news.ycombinator.com/item?id=33771922
        | 
        | [2] https://kristerw.blogspot.com/2017/09/why-undefined-
        | behavior...
 
        | Taywee wrote:
        | `x->foo()` in C++ often isn't just "crashy", but
        | undefined behavior. See https://en.cppreference.com/w/cpp
        | /utility/optional/operator*
        | 
        | > The behavior is undefined if *this does not contain a
        | value.
        | 
        | I'll take crashes over "probably does the wrong thing"
        | any day.
 
  | di4na wrote:
  | Pelikan is another example
 
  | pornel wrote:
  | Wrapping of C libraries in a Rust interface works quite well,
  | and makes them safer. For stable battle-tested libraries I
  | think it's even preferable to rewrites.
  | 
  | Many informal rules of C libraries like: "don't call read()
  | after close()", "pointer must never be null", or "keep this
  | data alive for as long as the handle is in use" in Rust can be
  | expressed using the type system, and enforced at compile time.
  | Cleanup can be automated. This catches bugs in user code and
  | shields the library form misuse.
 
  | cesarb wrote:
  | > but I'm thinking of a project where more substantial
  | additions have been made.
  | 
  | The most famous example of that is AFAIK Firefox. There's a
  | (perhaps outdated) list at
  | https://wiki.mozilla.org/Oxidation#Rust_Components of places
  | where Rust was used to replace some component in Firefox; the
  | most famous of these are probably the CSS style calculation
  | which came from the Servo project
  | (https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-
  | en...), and a renderer also from the Servo project
  | (https://hacks.mozilla.org/2017/10/the-whole-web-at-
  | maximum-f...).
 
| Decabytes wrote:
| Good to see some concrete evidence comparing memory unsafe
| languages to memory safe languages in an existing product. I just
| watched the Lex Fridman Guido Van Rossum episode and Rust vs
| C/C++ appears to be mirroring the trajectory Perl vs Python took
| in the ML/Bioinformatics space. Only time will tell whether Rust
| will reach the critical mass necessary to displace C/C++ in most
| new low level projects, but it appears clear to me that Memory
| Safe Languages which ever they may be are the future.
| 
| I don't need to program in an environment where a systems
| programming language is required, so for me a languages
| debugability and introspective capabilities are the most
| important. So far I think Pharo hits the sweet spot for me, but
| it still has a long way to go documentation wise before I think
| it will see any sort of adoption. I'm rooting for it though.
 
  | est31 wrote:
  | > Only time will tell whether Rust will reach the critical mass
  | necessary to displace C/C++ in most new low level projects
  | 
  | As someone who has been in the Rust community since a couple of
  | months after 1.0, I only see growth, year after year. At the
  | start the community was small. Nowadays even the OSS part of
  | it, which is a subset of the total community, is so big you
  | can't have an overview of it any more. Even for the Rust
  | project itself it's hard to have an overview over everything
  | that's happening (but it's still possible to some degree).
 
    | pornel wrote:
    | https://lib.rs/stats
    | 
    | crates.io downloads keep growing exponentially, although
    | recently growth rate dipped from 2x to 1.9x (not sure if
    | that's a trend or noise). Ratio of weekday to weekend
    | downloads keeps going up, so presumably professional adoption
    | of Rust keeps growing.
 
| WoodenChair wrote:
| The more interesting part of this article for me is that in 2022,
| Java is still the number 1 language that new pieces of Android
| are made out of. It probably has to be this way for
| compatibility, and I personally have no problem with Java. But
| the hype train would not have you believe this.
 
| lolinder wrote:
| Their notes about vulnerability _severity_ are particularly
| interesting.
| 
| Defenders of C/C++ frequently note that memory safety bugs aren't
| a significant percentage of the total bug count, and argue that
| this means it's not worth the hassle of switching to a new
| language.
| 
| Google's data suggests that while this is true, almost all
| _severe_ vulnerabilities are related to memory safety. Their
| switch to memory-safe languages has led to a dramatic decrease in
| critical-severity and remotely-exploitable vulnerabilities even
| as the total number of vulnerabilities has remained steady.
 
  | [deleted]
 
  | ghostwriter wrote:
  | > and argue that this means it's not worth the hassle of
  | switching to a new language.
  | 
  | Defenders of C++ argue that there's no reason to change the
  | language, because new features around safety guarantees are
  | being introduced into every C++ standard starting from C++11 at
  | a remarkable pace, so remarkable that compilers implement them
  | faster than the existing adoption rate. And the adoption rate
  | speaks volumes about existing capacity to port/rewrite big
  | codebases in entirely new stacks. The new stacks also tend to
  | have fewer custom static code quality analyzers from third-
  | party vendors, and they are used a lot in mission-critical C++
  | codebases.
 
    | lolinder wrote:
    | > The new stacks also tend to have fewer custom static code
    | quality analyzers from third-party vendors, and they are used
    | a lot in mission-critical C++ codebases.
    | 
    | Are these static code quality analyzers detecting code
    | quality problems that Rust and company are also vulnerable
    | to? Or are they mostly looking out for the hundreds of legacy
    | footguns that C++ still officially supports?
 
      | ghostwriter wrote:
      | They focus on quality control and compliance to safety
      | requirements in specific domains and industries, for
      | instance MISRA.
 
        | estebank wrote:
        | This might be of interest
        | https://github.com/PolySync/misra-rust
 
    | Ar-Curunir wrote:
    | Google is one of the biggest C++ shops out there, and also
    | authors and maintains many of the static analysis tools and
    | safety features you mention.
    | 
    | If they're saying that C++ can't be saved, maybe they're
    | worth listening to.
 
  | yosefk wrote:
  | It's even worse. The majority, not of all bugs, but all
  | vulnerabilities (of all severities) _do_ come from memory
  | safety bugs. TFA:  "For more than a decade, memory safety
  | vulnerabilities have consistently represented more than 65% of
  | vulnerabilities across products, and across the industry."
  | 
  |  _On top of that_ , memory safety vulnerabilities are
  | disproportionately high severity: "Memory safety
  | vulnerabilities disproportionately represent our most severe
  | vulnerabilities. In 2022, despite only representing 36% of
  | vulnerabilities in the security bulletin (NOTE: down to 36%
  | from 65% because of moving from C++ to Rust and other memory
  | safe languages), memory-safety vulnerabilities accounted for
  | 86% of our critical severity security vulnerabilities, our
  | highest rating, and 89% of our remotely exploitable
  | vulnerabilities. Over the past few years, memory safety
  | vulnerabilities have accounted for 78% of confirmed exploited
  | "in-the-wild" vulnerabilities on Android devices."
 
  | harry8 wrote:
  | Seems like drawing too many conclusions from evidence while
  | arguing against a straw man?
  | 
  | Defenders of C might note that Android is java and IOS is not
  | and compare the security of those two systems and say clearly
  | memory-safe is focusing on the wrong thing. This is equally
  | true but no more valid an argument.
  | 
  | The one that really bothers me in all these language-booster
  | discussions (that we should and need to have) is the functional
  | programming formal verification claims. We have no ssl library
  | written in a memory-safe, functional language that has been
  | proven correct that has dominated the space. Heartbleed wasn't
  | yesterday.
  | 
  | I look down the list here:
  | https://en.wikipedia.org/wiki/Comparison_of_TLS_implementati...
  | 
  | And I think something is not being discussed as far as
  | replacing memory unsafe languages of critical security
  | infrastructure. What is it?
 
    | ghostwriter wrote:
    | > We have no ssl library written in a memory-safe, functional
    | language that has been proven correct that has dominated the
    | space. Heartbleed wasn't yesterday.
    | 
    | Heartbleed didn't affect
    | https://hackage.haskell.org/package/tls even though it isn't
    | formally verified.
 
      | harry8 wrote:
      | Does anybody at all use that library in production at
      | scale, ever? Genuine question. Maybe they do?
      | 
      | Why hasn't this really good result meant _everybody_ now
      | uses that library by default and has to justify using
      | something else?
      | 
      | There is something here not being discussed, what is it?
 
        | ghostwriter wrote:
        | There's a hint it was used at Dell in some capacity 6
        | years ago, judging by this comment https://www.reddit.com
        | /r/haskell/comments/5gyrdv/what_is_war... The thread
        | discusses "warp-tls" which is a webserver extension that
        | uses that "tls" package as a dependency for TLS support.
 
  | rob74 wrote:
  | ...but still, even with Android's importance and Google's
  | resources, they're not planning to "rewrite it in Rust", at
  | least not for now - only new code will use Rust.
 
    | estebank wrote:
    | New code includes rewrites, like the Bluetooth stack.
 
    | lolinder wrote:
    | The overwhelming majority of bugs of any sort live in new
    | code. The longer a piece of code has been around, the safer
    | it generally is (with occasional high-profile exceptions).
    | This means two things:
    | 
    | 1) The most cost-effective way to eliminate the majority of
    | memory bugs is to just start writing all new code in a
    | memory-safe language. If you were going to write new code
    | anyway, you may as well do it safely.
    | 
    | 2) Going back and re-writing existing code that doesn't
    | _need_ to be changed may solve latent memory bugs, but it
    | will likely introduce other regressions that could be worse
    | for security or for user experience. If code doesn 't need to
    | change, it's often better to leave it as is.
    | 
    | Not that a rewrite is never called for, but it's not
    | necessarily the best course of action by any metric (even
    | when neglecting the cost).
 
  | gnull wrote:
  | > Defenders of C/C++ frequently note that memory safety bugs
  | aren't a significant percentage of the total bug count, and
  | argue that this means it's not worth the hassle
  | 
  | This says more about those C++ defenders.
 
    | hinkley wrote:
    | You can judge a person by the company they keep.
 
      | munificent wrote:
      | Lie down with C++, wake up with bugs.
 
| cjg wrote:
| Nice: "it's likely that using Rust has already prevented hundreds
| of vulnerabilities from reaching production"
 
  | heather45879 wrote:
  | The problem with Rust is the language syntax is ugly. It has a
  | ton of visual noise.
  | 
  | I think folks who write languages should have a typographer on
  | their team because something like this:
  | 
  | use std::collections::HashMap
  | 
  | Is a typographic nightmare. While I understand "form follows
  | function", it's tough to be excited to program in something
  | like this.
 
    | Mesopropithecus wrote:
    | As somebody who appreciates Lisp, I feel your pain. As
    | somebody who also appreciates Rust, I'm curious, what is your
    | baseline?
 
      | heather45879 wrote:
      | Good design theory.
      | 
      | https://www.doverbooks.co.uk/point-and-line-to-plane
      | 
      | Consider h::i::j::k versus h.i.j.k
      | 
      | Two :'s is an extremely loud combination of visual elements
      | compared to the subtle point. :: drags the eye away from
      | the content and says "look at me oscillate"
      | 
      | In addition, humans group similar visual elements together
      | so a combination of
      | anything::doesnt::matter::what::between::clumps it is
      | impossible to escape the common pattern and the eye jumps
      | between the ::'s. Therefore it takes double the cognitive
      | load to read.
      | 
      | What's worse, the eye gets trapped within each :: because
      | it's a combination of four dots, which naturally creates an
      | implied circular pattern which draws the viewer in further.
      | 
      | Compare to something like: use HashMap from std.collections
      | 
      | Or... more obviously the python import statements.
 
      | satvikpendem wrote:
      | Brainfuck, clearly /s
 
    | pcwalton wrote:
    | I was responsible for that decision, and I'm also a
    | typographer (worked for years on vector rendering of fonts).
    | :)
 
      | metaltyphoon wrote:
      | What reason were used to not use what C# has? It's
      | infinitely less noisy than Rust's ::
 
        | munificent wrote:
        | Technically, it is only 75% less noisy.
 
        | pcwalton wrote:
        | Using a separate character for namespace resolution and
        | field indexing allows you to have a module with the same
        | name as a value.
 
        | metaltyphoon wrote:
        | Wouldn't this be trivially solved by having namespaces
        | follow the same PascalCase semantics as types?
        | 
        | I.e
        | 
        | use Std.String;
        | 
        | .... let string = String(...);
 
    | nequo wrote:
    | It seems unlikely that it's the double colons and the angle
    | brackets that hold people back from migrating from C and C++
    | to Rust.
 
      | est31 wrote:
      | Yeah Rust's syntax was inspired to be similar to C++.
 
    | lawn wrote:
    | I do agree that Rust sometimes has a lot of visual noise.
    | 
    | But that use statement is not a good example of it, and if
    | that's the biggest criticism then Rust is faring
    | fantastically well.
 
      | IshKebab wrote:
      | Yeah I agree. Rust is a mildly ugly language, but not
      | because of `use`! It's all the lifetime annotations,
      | turbofish, and macros that make it ugly.
 
    | Manishearth wrote:
    | I always say that if the strongest complaint people have
    | about your language is syntax; you've already succeeded.
 
      | warkdarrior wrote:
      | You have an extra semicolon in your comment.
 
        | estebank wrote:
        | It's two statements, comments start with //
        | 
        | :o)
 
        | IIsi50MHz wrote:
        | It's "clearly" wrapped in hidden delimiters so that the
        | server regards it as a comment, though. (-;
 
| Kukumber wrote:
| Another failure for Kotlin Native, what a sad shitshow..
| 
| They were warned many years ago about
| ownership/concurrency/compile speed, they didn't listen at all
| 
| A vision alone doesn't matter, you need skilled engineers and a
| dedicated team who understand what "taste" for great things is
| 
| What could have been the Swift for android will end up just being
| the "java" alternative, i suspect they'll get rid of the JVM, or
| whatever the tech is, altogether and focus on Rust for whatever
| they plan next (maybe Fuschia), maybe there is still hope for
| Swift, we'll see
 
| thesuperbigfrog wrote:
| "Migrating away from C/C++ is challenging, but we're making
| progress. Rust use is growing in the Android platform, but that's
| not the end of the story.
| 
| To meet the goals of improving security, stability, and quality
| Android-wide, we need to be able to use Rust anywhere in the
| codebase that native code is required. We're implementing
| userspace HALs in Rust. We're adding support for Rust in Trusted
| Applications. We've migrated VM firmware in the Android
| Virtualization Framework to Rust.
| 
| With support for Rust landing in Linux 6.1 we're excited to bring
| memory-safety to the kernel, starting with kernel drivers."
| 
| The push for Rust to replace C and C++ continues.
| 
| This is confirmation of the NSA recommendation to discontinue
| using C and C++:
| 
| https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...
| 
| If you do not know Rust, now is the time to learn:
| 
| https://doc.rust-lang.org/book/
| 
| Here are some fun holiday-themed exercises to learn with:
| 
| https://adventofcode.com/
| 
| I plan on doing Advent of Code in Rust this year.
 
  | wiseowise wrote:
  | Actually now is the time to learn C++. Amount of leverage and
  | money C++ developers will be able to utilize is enormous, given
  | how much critical code is written in it.
 
    | thesuperbigfrog wrote:
    | >> Actually now is the time to learn C++. Amount of leverage
    | and money C++ developers will be able to utilize is enormous,
    | given how much critical code is written in it.
    | 
    | The article states:
    | 
    | "We continue to invest in tools to improve the safety of our
    | C/C++. ... Vulnerabilities found using these tools
    | contributed both to prevention of vulnerabilities in new code
    | as well as vulnerabilities found in old code that are
    | included in the above evaluation."
    | 
    | "These are important tools, and critically important for our
    | C/C++ code. However, these alone do not account for the large
    | shift in vulnerabilities that we're seeing, and other
    | projects that have deployed these technologies have not seen
    | a major shift in their vulnerability composition. We believe
    | Android's ongoing shift from memory-unsafe to memory-safe
    | languages is a major factor."
    | 
    | "our Rust code is proving to be significantly safer than pure
    | C/C++ implementations."
    | 
    | C++ is great if you do not have alternatives.
    | 
    | If you can use Rust instead of C / C++, you should because of
    | the greater safety it offers with similar performance
    | characteristics.
 
      | maeln wrote:
      | I think he meant it in a way the same way that some people
      | are still learning COBOL: a lot of critical, legacy code is
      | written in C++ and cannot easily (or won't be for various
      | reason) moved to another langage. Therefore, developer that
      | can maintain a C++ codebase might become invaluable for
      | some company.
 
      | cwyers wrote:
      | I believe what the post you're replying to is implying is,
      | there's a ton of C++ code in the world that isn't going to
      | be ported to Rust, and someone is going to have to fix all
      | of those bugs in C++ code already in the wild. So you can
      | get paid to be that person.
 
        | thesuperbigfrog wrote:
        | >> there's a ton of C++ code in the world that isn't
        | going to be ported to Rust, and someone is going to have
        | to fix all of those bugs in C++ code already in the wild.
        | So you can get paid to be that person.
        | 
        | That is well and good for legacy systems that cannot /
        | will not be updated.
        | 
        | Android is not a legacy system and is adopting Rust and
        | seeing security benefits.
        | 
        | Linux is not a legacy system and is slowly adopting Rust
        | and may see greater use with time.
        | 
        | Time will tell, but so far the future is optimistic.
 
        | depereo wrote:
        | They do say in the article that they are uninterested in
        | rewriting existing c/c++ code in new languages.
        | 
        | There will continue to be c/c++ applications that will
        | need new features, new bug fixes and new development for
        | decades.
        | 
        | Some of the most fundamental code on the planet for the
        | most critical systems are written in those languages.
        | Also a lot of video game development leans heavily on c++
        | in particular and that's not going to change very
        | quickly. Big or small enterprise hardware vendors won't
        | change to new languages overnight, abandoning potentially
        | decades of system building experience and supporting
        | processes. There's a cost to even being able to run rust
        | alongside your c/c++ code. Some places may never switch
        | or enable interoperability even for new products.
        | 
        | Learning c/c++ will still be lucrative and a good idea
        | today.
 
        | netr0ute wrote:
        | > Android is not a legacy system and is adopting Rust and
        | seeing security benefits.
        | 
        | > Linux is not a legacy system and is slowly adopting
        | Rust and may see greater use with time.
        | 
        | 100% USDA Grade-A Certified Prime BS, as shown by both
        | projects' ages (15+, 30+ years) and maybe the definition
        | of legacy. If you consider legacy to be something you
        | have to keep a certain way so that it functions a certain
        | way, then both are basically legacy technologies. What
        | isn't legacy? I would say projects like Fuchsia and Rust
        | itself aren't legacy because you can move fast and break
        | things there. This also means stuff like C++ is legacy,
        | so there's that too.
 
        | thesuperbigfrog wrote:
        | >> 100% USDA Grade-A Certified Prime BS, as shown by both
        | projects' ages (15+, 30+ years) and maybe the definition
        | of legacy
        | 
        | How should 'legacy' be defined?
        | 
        | If the software is actively developed and gets new
        | features regularly, I would not consider it legacy.
        | 
        | If the software only gets maintenance / bug fix updates
        | or is not updated, but is still used in production, then
        | it is legacy software.
        | 
        | >> I would say projects like Fuchsia and Rust itself
        | aren't legacy because you can move fast and break things
        | 
        | Fuchsia is not widely used (yet?). I am not sure how much
        | "moving fast and breaking things" happens in Fuchsia.
        | 
        | Rust has the concept of editions (https://doc.rust-
        | lang.org/edition-guide/editions/index.html) and spends
        | significant effort to maintain backward compatibility.
        | 
        | You do not have to "move fast and break things" to not be
        | legacy.
 
    | littlestymaar wrote:
    | I don't think it's worth the pain _to learn_ C++ today. Of
    | course, expert or just senior C++ developers have a bright
    | future ahead (even though their domain will slowly becomes
    | more niche every year), but for someone starting their career
    | now, I doubt they 'll reach the expert level before it has
    | lost most of its relevance.
 
      | wiseowise wrote:
      | Time will tell.
 
    | synergy20 wrote:
    | I'm learning modern c++ these days, but I don't follow your
    | 'money' logic here...
 
      | wiseowise wrote:
      | Cool kids and students move to Rust, C++ doesn't have
      | influx of new developers hence more demand for existing C++
      | developers.
 
  | satvikpendem wrote:
  | > _I plan on doing Advent of Code in Rust this year._
  | 
  | Nice, I'm doing it in chatGPT this year [0].
  | 
  | [0] https://news.ycombinator.com/item?id=33821092
 
| codedokode wrote:
| Rust doesn't check for overflow in arithmetic operations in
| release mode so there are lot of opportunities to create
| vulnerabilities in Rust.
 
  | maeln wrote:
  | This is how I discovered that one of my code was "bugged". I
  | had to implement a driver for an obscure chinese-made machine
  | with a documentation google translated. In the protocol, there
  | was a check byte and the explanation says that it was the 100
  | modulo of the sum of all previous byte. They didn't mention
  | overflow. I tested it using a release build and it was working.
  | Later on, while changing a few thing, I notice that the debug
  | build was not working. I quickly find that this was because of
  | the overflow behavior.
 
  | robot_no_421 wrote:
  | If you want to check for overflow, then you can use the methods
  | that explicitly check for overflow:
  | 
  | https://doc.rust-lang.org/std/primitive.u32.html#method.chec...
  | 
  | So this is not an issue at all.
 
  | burntsushi wrote:
  | There is some important context missing from your comment here.
  | At least two points anyway:
  | 
  | In Rust, overflow is not undefined behavior (neither signed nor
  | unsigned). Today, arithmetic wraps in release mode (panics in
  | debug mode), but it may panic in release mode in the future.
  | 
  | The other point is that, since overflow wraps, that may indeed
  | result in logic bugs. And in theory that logic bug could be
  | used to lead to exploit, such as a buffer overrun. But Rust
  | uses bounds checking by default everywhere, so the worst case
  | you'll usually end up with here is a panic or a DoS
  | vulnerability. Not great, but probably preferable to other
  | types of vulns that grant access to sensitive data.
  | 
  | So I think two things would need to happen, at minimum, to get
  | a non-DoS vulnerability here. You'd need to find a bug that
  | caused arithmetic to overflow where it otherwise shouldn't,
  | _and_ you need to find some way to connect that to an
  | explicitly `unsafe` unchecked access into memory.
 
    | Arnavion wrote:
    | >You'd need to find a bug that caused arithmetic to overflow
    | where it otherwise shouldn't, and you need to find some way
    | to connect that to an explicitly `unsafe` unchecked access
    | into memory.
    | 
    | Yes, it's particularly a dangerous problem when doing FFI. Eg
    | you have a `data: &[u8]` and you need to call `extern "C" fn
    | foo(data: *const u8` and `data_len_in_bits: usize)`, you
    | could write `data.len() * 8` for the second parameter and
    | Rust wouldn't stop you.
    | 
    | It's also annoying that the only way to do checked arithmetic
    | is replace all the simple arithmetic operators with
    | `.checked_*()?` function calls. libstd doesn't have a
    | `std::num::Checked` like it has `Wrapping` that would
    | implement all the arithmetic traits in terms of `checked_*`
    | and return `Result<>`. But at least it's not hard to do
    | yourself. ( https://github.com/Arnavion/terminal/blob/475d917
    | 377eea43b52... )
 
    | masklinn wrote:
    | An other thing to note is that java does not check for
    | overflow either. Having the "native" langage be no worse than
    | the "managed" one is a better situation to be in than the
    | reverse.
    | 
    | Also Rust allows enabling overflow checking in release, it's
    | a perfectly valid configuration.
 
    | estebank wrote:
    | Beyond the above, IIRC Android ships with integer overflow
    | enabled (but can't find where I read this).
 
      | est31 wrote:
      | You can confirm it by looking into the source code:
      | 
      | https://android.googlesource.com/platform/build/soong/+/ref
      | s...
      | 
      | Not an expert, but a file named "global.go" makes me
      | confident :).
 
      | insanitybit wrote:
      | Not that it's important, but just a note that unless you
      | recompile the standard library yourself, integer overflow
      | will still be off for that code since it ships compiled.
      | (Correct me if I'm wrong, that's my recollection).
 
        | est31 wrote:
        | The Android project compiles the standard library
        | themselves: https://android.googlesource.com/platform/pre
        | builts/rust/+/a...
 
        | insanitybit wrote:
        | Figures, thanks.
 
    | codedokode wrote:
    | Wrapping arithmetic operations have been a reason of
    | vulnerabilities in Linux kernel though. Developers need real
    | addition, not addition modulo 2^32.
 
      | burntsushi wrote:
      | I don't understand if you're disagreeing with me or writing
      | something that you think is inconsistent with what I said.
      | Because I don't see anything inconsistent between what I
      | said and what you wrote.
 
| faitswulff wrote:
| No mention of Carbon among the new memory safe languages. I
| wonder what inside baseball is at play with language selection.
 
  | UncleMeat wrote:
  | Carbon is not production ready yet. It doesn't even have a
  | publicly available compiler (just an interpreter). Carbon is
  | more about answering "what do we do with the billions of lines
  | of C++ code we've got" than "what is the best way to add new
  | code to a system."
 
| insanitybit wrote:
| Glad to see robust work here. This strongly supports what should
| already be obvious, but sadly is not always understood; that
| memory safe languages are radically safer than memory unsafe
| languages. The impact is blatantly demonstrated here.
 
  | stonemetal12 wrote:
  | When Heartbleed was a topic of discussion, some pointed out
  | that Rust wouldn't have 100% protected from that vulnerability.
  | So it is good to see some proof that using a safer language
  | does in fact pay off in terms of fewer defects. I just wish
  | there were some info around cost associated with development
  | effort. Did the Rust code take longer to develop? If initial
  | development was longer, what if we include time saved from
  | reduced effort for bug resolution?
 
    | eklitzke wrote:
    | Rust and C++ are about equally difficult (or easy) to program
    | in, the languages are much more alike than they are
    | different.
 
    | estebank wrote:
    | An example from an experiment to benchmark Rust and Java I
    | did recently, where I sent files from one app to another:
    | perf was good enough without tuning, with tuning I could
    | triple the speed and final total time on both versions was
    | comparable. Memory was much greater for Java (even with
    | graalvm). The Rust version didn't suffer from any memory
    | safety issues or race conditions when sending multiple files,
    | but I did have a vuln where you could specify a relative path
    | that could escape and write anywhere in the receiver's
    | filesystem. Rust didn't protect me from that, and those are
    | the kind of vulnerabilities that we'll continue seeing
    | regardless of language. But the threat surface I had to be
    | scared about was much smaller than it would have been in
    | other languages. And because the fallible APIs are obvious, I
    | handled many edge cases that I might have forgotten about
    | otherwise.
 
      | j-krieger wrote:
      | >Rust didn't protect me from that, and those are the kind
      | of vulnerabilities that we'll continue seeing regardless of
      | language
      | 
      | I'm still thinking about how we could integrate something
      | like that in a language or the languages package manager.
      | I'm unsure if it's possible.
 
        | manbart wrote:
        | How about in the OS? This sounds like exactly the type of
        | thin SELinux is meant to handle
 
        | insanitybit wrote:
        | Yeah, I think the thing is... path traversal is pretty
        | trivial to solve. If you have a single tenancy app and
        | you just don't want the service accessing shit it
        | shouldn't just throw it in docker. If you have a multi-
        | tenancy app just put every user behind a uuid.
 
        | estebank wrote:
        | The only things I can think of is the use of newtypes
        | around PathBuf that enforces things like expansion and
        | that makes the check for you when restricting tk a
        | specific directory. Now that I'm writing this out, this
        | feels like it could be a very useful small crate or
        | addition to Camino. Thank you for making me think further
        | about this. Of course, the impl would have an associated
        | runtime cost for the check and a more involved API
        | surface because it's asking the developer for more
        | information. But once you do that you can have an
        | TryInto impl to pass it to any standard method.
 
        | fiedzia wrote:
        | It's possible and easy (have types for path coming from
        | untrusted source), but it's a matter of a standard
        | library rather than a language.
 
        | stonemetal12 wrote:
        | In C++\Java this would be solved by a static analysis
        | tool. For example Fortify covers this error.
 
      | mcronce wrote:
      | > Rust didn't protect me from that, and those are the kind
      | of vulnerabilities that we'll continue seeing regardless of
      | language.
      | 
      | It didn't on its own, but it is worth noting that with
      | type-safe languages, you can protect yourself from this by
      | encoding that invariant into the type system.
      | 
      | Using Rust as an example, take a &std::path::Path (or
      | &camino::Utf8Path or whatever) in your public API; have
      | custom InternalPathBuf and InternalPath types that perform
      | validation to ensure they aren't using relative paths to
      | "break out" during construction, and then pass those around
      | in your internal API. Bingo bango, now there's no way
      | (short of transmuting, an `unsafe` operation) to pass
      | invalid paths to the functions that hit the filesystem
      | without a compile error. No redundant runtime checks
      | required, and no need for you as the developer to keep
      | track of which codepaths have already validated a Path and
      | which haven't.
      | 
      | I'm sure you already know this, and I would imagine that
      | Java can do the same, but it's a big step above languages
      | like Python where you can do whatever you want to anything
      | you want.
      | 
      | EDIT: lol while I was typing this you made a post about the
      | same thing below.
 
        | estebank wrote:
        | Great minds and all that :)
        | 
        | I guess it is also an often used square peg that fits
        | really nicely in the square Rust typesystem hole (no, not
        | talking about _those_ typed holes, haskellers).
 
  | cyber_kinetist wrote:
  | Rust (despite the common understanding) is not a memory-safe
  | language in its entirety. It is a language designed to have a
  | strict division of safe/unsafe which makes it easier for
  | developers to compartmentalize code to achieve memory-safety.
 
    | insanitybit wrote:
    | No language in use meets your definition of memory safe.
 
      | pclmulqdq wrote:
      | Ada seems to fit.
 
        | insanitybit wrote:
        | A simple heuristic that I expect to work universally is
        | "could I write a program that prints to my terminal on a
        | linux machine?" and if the answer is "yes" then it does
        | not fit.
 
        | burntsushi wrote:
        | Ada has no "unsafe"? Ada has no ffi? Ada has no escape
        | hatches or unchecked APIs whatsoever? Does it have any
        | pragmas that can disable safe checking? Because if it
        | does, it's not "entirely" memory safe.
 
        | thesuperbigfrog wrote:
        | Ada has "unchecked" operations:
        | 
        | Unchecked Access (unsafe pointers): http://www.ada-
        | auth.org/standards/22rm/html/RM-13-10.html#I5...
        | 
        | Unchecked Deallocations ("free"): http://www.ada-
        | auth.org/standards/22rm/html/RM-13-11-2.html#...
        | 
        | Unchecked type conversions (unsafe casting):
        | http://www.ada-
        | auth.org/standards/22rm/html/RM-13-9.html#I57...
        | 
        | Ada has FFI:
        | 
        | C / C++: http://www.ada-
        | auth.org/standards/22rm/html/RM-B-3.html
        | 
        | COBOL: http://www.ada-
        | auth.org/standards/22rm/html/RM-B-4.html
        | 
        | Fortran: http://www.ada-
        | auth.org/standards/22rm/html/RM-B-5.html
        | 
        | Ada has pragmas to both enable more security measures or
        | relax security measures:
        | 
        | http://www.ada-auth.org/standards/22rm/html/RM-L.html
        | 
        | Just like in unsafe Rust, sometimes in Ada you need to
        | turn off some security features or tell the compiler "I
        | know what I am doing for this part" when interfacing with
        | some hardware or similar low-level stuff.
 
        | [deleted]
 
        | pcwalton wrote:
        | Ada has an FFI.
 
        | modshatereality wrote:
        | As well as address clause, unchecked_conversion and
        | address_to_access_conversion. Extremely useful tools that
        | give you the choice when to write risky code, and
        | generate a compiler note exactly where such risk lives.
 
      | scj wrote:
      | Perhaps the problem is with the term "memory safe".
      | 
      | No language can prevent a person from allocating a writable
      | buffer, then reusing it without cleaning it. Do that on a
      | server, and you have step 1 to a security vulnerability.
      | 
      | If requests to allocate memory come faster than the garbage
      | can be collected.
      | 
      | Or a data container holding many/large references that will
      | never be used. The difference between that and a lost
      | pointer in C are moot in a practical sense.
      | 
      | All of these _can_ be prevented. But it's programmer care,
      | rather than the language, that prevents them. Hence, the
      | term "memory safe" is inaccurate. "Memory safer" would be
      | more accurate, but far less catchy.
 
    | burntsushi wrote:
    | Is there any practical programming language that is memory
    | safe in its "entirety"? Python, for example, certainly is
    | not. It has unsafe escape hatches (via ffi, at the very
    | least). Yet, everyone I know of says and thinks of Python as
    | a memory safe language. I do as well.
    | 
    | > which makes it easier for developers to compartmentalize
    | code to achieve memory-safety
    | 
    | The problem here is that this is incomplete. Many many many
    | languages have achieved this before Rust. Where Rust is
    | (somewhat although not entirely) unique is bringing this
    | compartmentalization into a context that (mostly) lacks a
    | runtime and garbage collection.
    | 
    | I have no problems calling Rust a "memory safe language"
    | precisely because I have no problems calling Java or Python
    | "memory safe languages." What matters isn't whether the
    | language is "entirely" memory safe. What matters is what its
    | default is. C and C++ are by default unsafe everywhere. Rust,
    | Java, Python and many others are all safe by default
    | everywhere. This notion is, IMO, synonymous with the more
    | pithy "memory safe language."
 
      | cesarb wrote:
      | > It has unsafe escape hatches (via ffi, at the very
      | least).
      | 
      | Playing devil's advocate, I can think of at least one
      | language which has no escape hatches: Javascript running
      | within a web page.
 
        | burntsushi wrote:
        | Yes, but that's not just a language. It's a language
        | within a certain context. But it is a worthy mention.
 
      | bluGill wrote:
      | > Is there any practical programming language that is
      | memory safe in its "entirety"?
      | 
      | This isn't possible. Eventually you are sitting at a block
      | of memory and need to write the allocator. Maybe (like
      | python) your allocator is written in C and you hide it, but
      | there is always something that isn't memory safe sitting
      | under your language.
      | 
      | You could write a language for an actual Turing machine
      | which since it has infinite memory is by definition memory
      | safe. However as soon as you need to run on real hardware
      | you have to work with something unsafe.
      | 
      | You can of course prove a memory allocator is correct, but
      | it would still have to use unsafe in rust. I supposed you
      | could them implement this alloator in hardware, and make
      | rust use that - but since this doesn't seem like it will
      | happen I'm going with all languages have unsafe somewhere
      | at the bottom.
 
        | AnimalMuppet wrote:
        | That depends on your definition of "practical" and
        | "entirety".
        | 
        | The article was about languages being used to implement
        | Android. Clearly, no, you can't have an entirely memory
        | safe language that can be used to implement Android, for
        | the reason you said. But there's a wide gap between
        | "practical for doing useful work of any kind" and
        | "practical for implementing Android".
        | 
        | Then, "entirely". What's "entirely"? Entirely until you
        | get to library calls? Entirely until you get to OS calls?
        | Entirely _including the OS_? If you include the OS then
        | again, you are right for the reason you said. But if you
        | exclude the OS, I 'm not so certain.
 
        | burntsushi wrote:
        | Yes, exactly. That's why I asked the question: to drive
        | out the point that the ontology the GP was using was
        | probably not terribly useful.
        | 
        | Although I did use the weasel word "practical" to narrow
        | the field. If you don't limit yourself to general purpose
        | languages, then I'm sure you can find one that is
        | "entirely" safe.
 
      | masklinn wrote:
      | > It has unsafe escape hatches (via ffi, at the very
      | least).
      | 
      | Yep, ctypes is part of the stdlib and lets you corrupt the
      | VM on the fly. Fun stuff like changing the value of cached
      | integers and everything.
      | 
      | But ctypes being a terrifying pain in the ass, people tread
      | very carefully around it. Cffi's a lot better though it
      | requires an external package. At the end of the day I think
      | I'd be more enclined to bind through pyo3 or cython than
      | write C in python (which is what ctypes has you do without
      | even what little type system C has, to say nothing of -Wall
      | -Weverything).
 
        | rraval wrote:
        | > But ctypes being a terrifying pain in the ass, people
        | tread very carefully around it.
        | 
        | I'm not sure how much people treading carefully actually
        | translates into safety in practice.
        | 
        | CPython in particular has ad-hoc refcounting semantics
        | where references can either be borrowed or stolen and you
        | have to carefully verify both the documentation and
        | implementation of functions you call because it's the
        | wild west and nothing can be trusted:
        | https://docs.python.org/3.9/c-api/intro.html#reference-
        | count...
        | 
        | This ad-hoc borrowed vs stolen references convention
        | bleeds into cffi as well. If you annotate an FFI function
        | as returning `py_object`, cffi assumes that the reference
        | is stolen and thus won't increment the ref count.
        | However, if that same function instead returns a `struct`
        | containing a `py_object`, cffi assumes the reference is
        | borrowed and will increment the ref count instead.
        | 
        | So a harmless looking refactoring that changes a directly
        | returned `py_object` into a composite `struct` containing
        | a `py_object` is now a memory leak.
        | 
        | Memory leaks aren't so bad (even Rust treats them as safe
        | after the leakpocalypse [1] [2]). It's when you go the
        | other way and treat what should have been a borrowed
        | reference as stolen that real bad things happen.
        | 
        | Here's a quick demo that deallocates the `None`
        | singleton:                   Python 3.9.13 (main, May 17
        | 2022, 14:19:07)         [GCC 11.3.0] on linux
        | Type "help", "copyright", "credits" or "license" for more
        | information.         >>> import sys         >>>
        | sys.getrefcount(None)         4584         >>> import
        | ctypes         >>> ctypes.pythonapi.Py_DecRef.argtypes =
        | [ctypes.py_object]         >>> for i in range(5000):
        | ...     ctypes.pythonapi.Py_DecRef(None)         ...
        | 0         0         0         0         0         [snip]
        | Fatal Python error: none_dealloc: deallocating None
        | Python runtime state: initialized              Current
        | thread 0x00007f28b22b7740 (most recent call first):
        | File "", line 2 in          fish: Job 1,
        | 'python3' terminated by signal SIGABRT (Abort)
        | 
        | [1]: https://rust-lang.github.io/rfcs/1066-safe-mem-
        | forget.html [2] https://cglab.ca/~abeinges/blah/everyone-
        | poops/
 
        | masklinn wrote:
        | > Here's a quick demo that deallocates the `None`
        | singleton:
        | 
        | As I said, you can trivially corrupt the VM through
        | ctypes. However I don't think I've ever seen anyone
        | wilfully interact with the VM for reasons other than shit
        | and giggles.
        | 
        | The few uses of ctypes I've seen were actual FFI
        | (interacting with native libraries), and IME it's rare
        | enough and alien enough that people tread quite carefully
        | around that. I've actually seen a lot less care with the
        | native library on the other side of the FFI call than on
        | the FFI call itself (I've had to point issues with that
        | just this morning during a code review, if anything the
        | ctypes call was over-protected, otoh the update to the
        | so's source had multiple major issues).
 
      | afdbcreid wrote:
      | Surely this is true, but I still have the feeling that
      | libraries in Rust tend to have more unsafe code than Java,
      | Python, C# or others, maybe even more unsafe code than
      | needed. Perhaps this is related to the problem domain.
 
      | fiedzia wrote:
      | > Is there any practical programming language that is
      | memory safe in its "entirety"?
      | 
      | Whatever can be compiled to BPF meets this requirement. The
      | price though is that it wouldn't be very useful.
 
        | burntsushi wrote:
        | Right, that's why I used the word "practical."
 
      | dahfizz wrote:
      | I think a distinction can be made in that you never really
      | need to use unsafe operations in python or Java. In rust,
      | you _need_ unsafe. Just about every data structure in the
      | stdlib uses unsafe.
      | 
      | I think it's fair to call Rust a memory safe language. But
      | I don't think it's on the same tier as a fully managed
      | language like python.
 
        | burntsushi wrote:
        | I suppose reasonable people can disagree, but I don't
        | think it's anywhere near as clear cut as you seem to be
        | implying. You talk about data structures in std using
        | unsafe, but you don't mention the heaps and piles of C
        | code used to implement CPython's standard library.
        | 
        | It's not like you need `unsafe` in Rust to build every
        | data structure. I build oodles of data structures on top
        | of the fundamental primitives provided by std without
        | using any `unsafe` explicitly whatsoever.
        | 
        | And it is not at all uncommon to write application code
        | in Rust that doesn't utter `unsafe` at all. Even ripgrep
        | has almost none of it. At the "application" level it has
        | exactly two uses: one related to PCRE2 shenanigans and
        | one related to the use of file backed memory maps. Both
        | of those things are optional.
        | 
        | Then there's another whole perspective here, which is
        | that if you're using Rust in the first place, there's a
        | non-trivial chance you're working on something "low
        | level" that might require `unsafe`. Where as with Python
        | you probably aren't doing "low level" work and just don't
        | care much about perf within certain contexts. That has
        | less (albeit not "nothing") to do with the design of the
        | languages and more to do with the problems you're trying
        | to solve.
        | 
        | To be clear, I am not saying you're definitely wrong. But
        | as someone who has written many tens of thousands of
        | lines of both Rust and Python, I would put them on the
        | same or very very close level in terms of memory safety
        | personally. Certainly within the same tier.
 
        | dahfizz wrote:
        | You make a good point that much of pythong stdlib is
        | implemented in C. But you _could_ implement python 's
        | list in pure python, safely. You can't implement
        | something like that in rust without unsafe.
 
        | kibwen wrote:
        | You can implement lists in Rust safely; with enums, a
        | list is four lines of safe code. You can even implement a
        | doubly-linked list safely. You just can't do either of
        | these things by wielding pointers willy-nilly. If you're
        | willing to accept a performance tradeoff by implementing
        | a list in pure, bootstrapped, FFI-free Python, then you
        | can do the same in Rust.
 
        | alserio wrote:
        | How would you implement a python list in python? I mean,
        | what would you consider "acceptable" primitives to do so?
 
        | burntsushi wrote:
        | You certainly can! And that's a good example, because it
        | exposes just how important context is to this discussion.
        | Perf matters in certain contexts. If you implemented a
        | list in pure Python, do you think its users would find
        | the overall perf of Python to be acceptable?
 
        | Ar-Curunir wrote:
        | One could implement many data structures without unsafe,
        | but with less efficiency. E.g. using an arena allocator
 
        | dahfizz wrote:
        | Sure, but that is kind of what I mean. Safety in rust is
        | something you actively have to think about and work
        | around (at least some of the time). It doesn't just come
        | for free like in python.
 
        | estebank wrote:
        | I would like to dispute the "with less efficiency"
        | simplification, because depensing on the size and usage
        | patterns of your code, a doubly linked list or sikilar
        | graph datastructure, backed by an arena will be _faster_
        | than the way those data structures appear in books.
 
        | kllrnohj wrote:
        | > I think a distinction can be made in that you never
        | really need to use unsafe operations in python or Java.
        | 
        | You can't write any code _at all_ in Python or Java
        | without relying on unsafe operations. Both of them have
        | their runtimes written in C /C++.
        | 
        | So based off of this unusual line of reasoning, Rust is
        | strictly more memory safe than either of those as it's at
        | least _possible_ to have a Rust program without any
        | unsafe code. That program will be of questionable value,
        | sure, but it can at least exist at all whereas it can 't
        | for Python or Java.
 
        | fiedzia wrote:
        | > You can't write any code at all in Python or Java
        | without relying on unsafe operations.
        | 
        | There are Python interpreters written in other languages:
        | there is one in Rust, and there is Jython and IronPython.
 
        | masklinn wrote:
        | > You can't write any code at all in Python or Java
        | without relying on unsafe operations. Both of them have
        | their runtimes written in C/C++.
        | 
        | Technically, pypy is a Python runtime written in Python.
 
        | dahfizz wrote:
        | By that logic, you can't write any safe rust _at all_
        | because it relies on a compiler written in C++.
        | 
        | We are discussing the languages themselves, not any
        | particular implementation.
 
        | steveklabnik wrote:
        | Only the codegen and many optimization parts of the
        | compiler is in C++. The rest of it is in Rust.
 
    | raphlinus wrote:
    | The blog speaks to this explicitly, in the "what about unsafe
    | Rust" section. The tl;dr is that the number of unsafe
    | sections is a small fraction of the total code size, and it's
    | much easier to audit the usage of unsafe, as the reason to
    | justify it is focused. Thus, the use of unsafe in Rust is not
    | a significant driver of actual vulnerabilities.
    | 
    | I think this has always been the goal, but it wasn't obvious
    | at the outset that it would be achievable. The fact that we
    | now have empirical evidence in real shipping products is
    | significant.
 
    | civopsec wrote:
    | Then even Java is not memory safe according to the implicit
    | standard that you allude to here since one can use the
    | `Unsafe` class.
 
      | [deleted]
 
| optymizer wrote:
| As an Android user ever since the T-Mobile G1, I'm a fan of not
| having my phone remotely exploited via WebView, or with an SMS,
| or the other million ways there are to interact with a device, so
| I absolutely celebrate this progress.
| 
| As an Android developer though, I have to be the one bitter old
| man yelling at cloud. I was spoiled by Java and Kotlin to the
| point where I cannot look at Rust and think it's a nice modern
| language.
| 
| Yes, I will start a language war today. Rust is like a truck
| driver who tried to make a race car that doesn't blow up. It's
| safe but it does not look refined. I wish you knew how weird Rust
| looks to me. I tried to learn it 3 times and had to give up after
| all the WTFs. I said it in the past, and I'll say it again:
| 
| * What the hell kind of language choice is to force everyone to
| type "#[derive(Debug)]" for annotations? I'd rather write past
| the end of an array and have someone steal my Bitcoin wallet than
| press "shift 3 bracket shift 9 shift 0 bracket" at the top of my
| structs. What's wrong with @? Nothing. @derive(debug). 2java4u?
| Ok, [derive debug] then.
| 
| * What's with the ' everywhere? Not the quote, the piece of dirt
| on your display. Why are our displays so dirty?
| 
| * Going for super short keywords "let", "fn", "mod", but then,
| "let mut" could have been "var". When is typing speed the
| bottleneck in writing software where you can't take the time to
| type out "module" or even 'function'? Come on now.
| 
| * print! now! fast! it's! a! macro! why! are! we! yelling!
| 
| * Passing "self" as the first argument was bullshit in Python,
| and it's bullshit in Rust too. Don't look at me like that - the
| compiler can inject it as the first parameter without requiring
| you to type it in.
| 
| * What does "::" do that "." can't? That's right. Nothing. All
| hail D.
| 
| D got language design right. Syntax better than Rust. CTFE better
| than Rust. Templates better than Rust. Marketing worse than Rust,
| though.
| 
| I'll try to learn Rust a 4th time now to stay relevant in the
| Android world, because I have bills to pay, but I want you to
| know that I blame each and everyone of you weirdos for not
| holding language designers to a higher bar.
| 
| Edit: if you downvote, reply with a link to the last compiler you
| wrote.
 
  | aliceryhl wrote:
  | > Rust is like a truck driver who tried to make a race car that
  | doesn't blow up.
  | 
  | Lamborghini originally made tractors.
 
  | pcwalton wrote:
  | > Edit: if you downvote, reply with a link to the last compiler
  | you wrote.
  | 
  | https://github.com/rust-lang/rust/
 
    | optymizer wrote:
    | upvoted <3
 
    | satvikpendem wrote:
    | This has to be as good as the "Did you win a Putnam?" comment
    | from 15 years ago [0].
    | 
    | [0] https://news.ycombinator.com/item?id=35079
 
  | throwup wrote:
  | So many complaints above surface-level syntax here.
  | 
  | > press "shift 3 bracket shift 9 shift 0 bracket" at the top of
  | my structs
  | 
  | Just use an IDE and you can press alt+enter. Same thing you do
  | in Java when writing getters and setters for your
  | AbstractFactoryBeans.
  | 
  | > "let mut" could have been "var"
  | 
  | The "mut" does not belong to the "let", it belongs to the
  | variable name.                 let (read_only, mut read_write)
  | = (1, 2);
  | 
  | > Passing "self" as the first argument was bullshit
  | 
  | Explicit is better than implicit. I quite like the names in the
  | argument list to match the set of names available in the
  | function, rather than having an extra keyword (`static`) that
  | you add to _remove_ a function parameter.
 
    | masklinn wrote:
    | > Explicit is better than implicit.
    | 
    | Not only that, but in Rust it actually has a meaning. Self
    | can be &self or &mut self, which impacts the calling
    | conventions.
    | 
    | The alternative would be fully typing anything but owned
    | method calls which would just not have a self parameter,
    | which would be incredibly weird.
    | 
    | It also shows that as in Python (and really even more so)
    | "methods" are little more than syntactic sugar for functions.
    | It would also require a new and separate syntax to declare
    | non-instance methods.
 
  | estebank wrote:
  | https://github.com/rust-lang/rust/pulls?q=is%3Apr+author%3Ae...
  | 
  | The aesthetics of syntax is a personal matter, but when the
  | critique of a language focuses exclusively on its syntax, it
  | tells me that the critique is skin deep. Semantics are way more
  | important to what code "feels" like to write.
  | 
  | Why not @derive? @ was a reserved token for something else
  | before 1.0 and today is still used in patterns. Now it's too
  | late to change.
  | 
  | The ' lifetime syntax was borrowed from another language. Some
  | way of differentiating types and lifetimes is necessary, ' is
  | not any worse than most others we could have chosen.
  | 
  | We try to make things that are common and safe terse, and
  | things that are uncommon and potentially problematic more
  | verbose. ? is common and safe, .unwrap() is less common and
  | potentially problematic. Mutable bindings are not exactly
  | unidiomatic, but mildly discouraged.
  | 
  | println! is a macro because it 1) is a compiler intrinsic to do
  | compile time magic like the recent addition of capturing
  | bindings directly in the formatting string and 2) it takes a
  | variable number of arguments. Differentiating between macros
  | and function calls is important if you want to get a sense for
  | what the code you're reading can do. You can choose another way
  | of differentiating them, but whatever you choose will be
  | subjective and has to mesh well with the rest of the language.
  | 
  | Explicit self makes it easy syntax to differentiate between
  | associated functions (part of the type) and methods (part of
  | the instance), while also making very clear when you're
  | accessing the current instance's data. And because Rust cares
  | about mutability and ownership, you still need to communicate
  | the differences between self, &self and &mut self. It also
  | provides syntactic space for arbitrary self types: fn foo(self:
  | Pin<&mut Self>)
 
  | netr0ute wrote:
  | I had the same experience with Rust too. After trying and
  | failing for hours to trudge through syntax BS, I'm (probably)
  | not touching it again until something big changes. I can't even
  | get user input without making a huge ugly one-liner or
  | importing some dependency.
 
    | nneonneo wrote:
    | Unclear what you mean by user input - for arguments,
    | `std::env::args()` exists, and for stdin `std::io::stdin()`
    | exists and provides various read functions.
    | let mut line = String::new();         stdin().read_line(&mut
    | line)?;         println!("input: {}", line);
    | 
    | I suspect that there _have_ been some changes since you last
    | looked - for example, the ? operator lets you propagate
    | errors in a more compact way.
 
      | netr0ute wrote:
      | let mut line = String::new();
      | stdin().read_line(&mut line)?;
      | 
      | This is what I'm talking about. This is so ugly and clunky
      | and needlessly verbose like Java compared to C++ where you
      | can do                   std::string input;
      | std::cin >> input;
      | 
      | and have it Just Work. Why can't Rust do something similar?
 
        | masklinn wrote:
        | Because Rust does not want to have implicit constructors,
        | default constructors, constructors at all, random
        | statics, ...
        | 
        | And `std::cin` does not read a line from the input, you
        | need `getline` for that.
 
        | oll3 wrote:
        | Not that this kind of stdin reading operation is
        | something I do often. But at least the Rust code says
        | what it does. Bitshifting stdin by a string on the other
        | hand... Does it read a line, or forever, or read at all?
        | I wouldn't call it the ultimate syntax for a line reader
        | anyway. :)
 
        | nneonneo wrote:
        | Except, you've failed to check for an error, and you need
        | another line to do that. Suppose the user ended their
        | input or the input is a pipe that's been closed - what
        | does your C++ program do?
        | 
        | Here's another example. C++ lets you do this:
        | long input;         std::cin >> input;
        | process(input);
        | 
        | and this is very convenient! It's much shorter than the
        | Rust code for doing the same. It's also wrong! If the
        | input cannot be read, or it cannot be parsed as an
        | integer, `input` now contains undefined content. You'd
        | need to remember to check the contents, or end up
        | processing undefined memory values. You _cannot_ make
        | this error in Rust without a lot of contortions (e.g.
        | unsafe).
        | 
        | Some people will say, I just want to get stuff done and
        | not worry about all this safety junk. As someone who
        | works in security and have exploited bugs in C/C++
        | programs, this is pretty much why we wound up with so
        | many CVEs.
 
  | j-krieger wrote:
  | > Passing "self" as the first argument was bullshit in Python,
  | and it's bullshit in Rust too. Don't look at me like that - the
  | compiler can inject it as the first parameter without requiring
  | you to type it in.
  | 
  | Nope, that would be a static function on your struct. By using
  | self you let the compiler know that you want to use an instance
  | function.
 
    | nneonneo wrote:
    | Also, there are several different ways to pass self: `self`,
    | `mut self`, `&self`, `&mut self`, and they have very
    | different semantics.
    | 
    | Rust could have taken the C++ route here: `fn static foo()`,
    | `fn foo()`, `fn mut foo()`, `fn &mut foo()`, etc. but I feel
    | like the explicit `self` is very clear and easy to
    | understand.
 
      | masklinn wrote:
      | > Rust could have taken the C++ route here: `fn static
      | foo()`, `fn foo()`, `fn mut foo()`, `fn &mut foo()`, etc.
      | 
      | `fn Box foo()`? `fn Arc foo()`? It also requires more
      | parser lookahead.
      | 
      | The `mut` case is also very odd, as it's not part of the
      | function API (it just configures the binding of the
      | internal local). Plus if self was implicit it likely would
      | need to be a keyword, so that wouldn't be a usecase at all
      | anymore.
 
    | optymizer wrote:
    | what if there's no static function with that name?
 
      | masklinn wrote:
      | There is since that's what you declared.
      | impl Foo {             // static             fn foo() {}
      | }              impl Foo {             // instance, owned
      | fn foo(self) {}         }              impl Foo {
      | // instance, borrowed             fn foo(&self) {}
      | }              impl Foo {             // instance, boxed
      | fn foo(self: Box) {}         }              impl Foo
      | {             // instance, refcounted             fn
      | foo(self: Rc) {}         }
 
        | phaylon wrote:
        | Small nitpick: Fortunately, `Rc` and `Arc` actually don't
        | require the nightly feature.
 
        | masklinn wrote:
        | Oh yeah you're right that's been stabilised, now that I'm
        | thinking about it, it was probably something like `self:
        | std::sync::MutexGuard<'_, Self>` which told me to enable
        | the feature
 
    | nevi-me wrote:
    | I prefer self. The changes in ES5 in JavaScript were painful
    | because some people kept losing track of `this`'s scope. IIRC
    | it changed with arrow functions, making it hard to know what
    | `this` the code was using.
    | 
    | I prefer an explicit `this` or `self` being passed, so that I
    | know where it's defined. Something close enough, Kotlin uses
    | `it` in lambdas. If you're nesting your lambdas, it can be
    | tricky to review the code when just staring at it (when the
    | IDE isn't helping you with types).
 
  | gavinray wrote:
  | I'm just commenting to agree with the "D got language design
  | right, Marketing worse than Rust". I cry every time =(
  | 
  | Don't have anything against Rust though, except the syntax can
  | be a bit obtuse.
 
  | shpongled wrote:
  | I find it interesting that your complaints are almost totally
  | about the syntax - that is generally the last thing I care
  | about in a language.
  | 
  | When I choose languages, I choose them based on semantics,
  | tooling, community/ecosystem, UX, and then _maybe_ syntax
 
    | netr0ute wrote:
    | For me, syntax is one of the top priorities because if I
    | can't express what I want using something compatible with how
    | I think, then it doesn't matter if the language has SuperLib
    | 4000 available if I can't program with it.
 
  | [deleted]
 
| jfengel wrote:
| I'm surprised that Kotlin is such a small fraction. I thought
| Google was trying to make Kotlin preferred over Java for Android
| development.
| 
| (Not that it's easy to tell from the pie chart, which colors one
| orange and the other red, in similar shades. Do better, guys.)
 
  | dragonwriter wrote:
  | Development _of_ Android and development _for_ Android are
  | different domains.
 
| LAC-Tech wrote:
| For me the biggest features of rust are:
| 
| - great standard library, especially all the iter methods. having
| 'obscure' stuff like `try_for_each` just makes me so happy as a
| dev
| 
| - unit tests built into the lang
| 
| - tooling is great
| 
| - docs are top notch
| 
| The memory safety aspect is... sometimes helpful, sometimes
| irritating. I prefer zig solution (BYO allocator, special one for
| testing that reports errors) over rusts, which simplifies a lot
| of stuff and lets you make cyclical data structures without a lot
| of hoop jumping.
 
  | pornel wrote:
  | Rust does require structuring programs in a "Rust way" to avoid
  | fighting with things it can't prove to be safe.
  | 
  | However, I appreciate that Rust tries to achieve safety through
  | improving program correctness, not merely crashing sooner.
  | 
  | Of course Rust has run-time panics (hasn't solved the halting
  | problem yet), but it also has many patterns catching problems
  | at compile-time. For example, a hardened allocator can detect
  | use-after-free bugs when they happen, but borrow checking can
  | prevent them from existing in the code in the first place.
 
    | Mesopropithecus wrote:
    | > Rust does require structuring programs in a "Rust way" to
    | avoid fighting with things it can't prove to be safe.
    | 
    | That was my concern that I had when I started learning the
    | language. I think it is true, but I was surprised how quickly
    | I managed to get used to the Rust way.
 
      | marcosdumay wrote:
      | The "Rust way" is very close to the safe variety of the
      | "experienced C++ way", so many people adapt promptly.
 
      | LAC-Tech wrote:
      | I'm surprised at how slowly I'm getting used to it!
      | 
      | I mean I've improved but I still have a lot of "wtf"
      | moments. End up doing a lot of deep copying and heap
      | allocations just to shut the compiler up, which makes me
      | question just how "zero cost" the safety is.
 
      | chc wrote:
      | It's also worth noting that the "Rust way" often ends up
      | being clearer and better structured, in hindsight. Rust
      | forces you to think through questions of ownership and
      | identity more than most languages, and a lot of
      | "structuring programs the Rust way" is just expressing
      | these things.
      | 
      | Of course, that's just "often," not nearly "always." There
      | are many valid programs that the borrow checker struggles
      | with, and in those cases, the "Rust way" is just needlessly
      | convoluted. There are many problems for which the most
      | common answer is "just store all this data in a list and
      | use list indices like pointers." (Thankfully there has been
      | a lot of progress on a new borrow checker that's less
      | easily startled.)
 
  | dist1ll wrote:
  | What I like about this language is the crazy amount of creative
  | and insightful discussions about language features and
  | stabilization.
  | 
  | It's because Rust hits the spot for MANY different domains and
  | people. System programmers, functional programmers, backend, db
  | engineers, GUI, devs from the formal verification/mission
  | critical camp, OS devs, graphics and even frontend with WASM.
  | 
  | For me personally, the thing I miss in Rust is better const
  | fn/comptime/metaprogramming (like in C++). Without them, I find
  | writing generic high-perf data structures quite tedious (and
  | proc macros just aren't a suitable replacement for generics)
 
    | j-krieger wrote:
    | I love Rust, but I kind of believe in the conspiracy that
    | comptime code features are less loved by the Rust language
    | maintainers because they increase compile time even more.
 
      | Ar-Curunir wrote:
      | That directly contradicts in-progress efforts to make
      | `const` better. Things like `const trait`, `const
      | Allocators`, etc are all in progress.
 
        | andrewflnr wrote:
        | "In progress" does not (by itself anyway) contradict
        | "less-loved". Something can be in progress but making
        | slower progress than it would if people were really
        | excited about it.
 
        | dist1ll wrote:
        | Some const features seem like big anti-patterns though.
        | One example is the unstable feature `generic_const_exprs`
        | which I think is a bit short-sighted.
 
        | chc wrote:
        | What seems short-sighted about that to you? I'm not super
        | familiar, but it seems like something you'd want if
        | you're using const generics.
 
      | estebank wrote:
      | This isn't the case, it's just that the approach to bring
      | comp time evaluation to Rust is difficult because we're
      | trying to side step potential back compat or ambiguous
      | restrictions that we otherwise would have. Rust follows the
      | "when it's ready" delivery approach wich means that some
      | eagerly awaited features take much longer than us, as
      | users, would want.
 
        | satvikpendem wrote:
        | Which I appreciate. I don't want Rust turning into
        | another C++ in 20 years.
 
  | amalcon wrote:
  | Honestly, my favorite parts about rust are:
  | 
  | - It has the best parts of C (code generation is predictable,
  | no mandatory extra thread for GC or similar, interoperates very
  | well with C code)
  | 
  | - It also has some of the niceties that were popularized after
  | C (type inference, an equivalent of unions that isn't terrible,
  | macros that are not terrible, functional features)
  | 
  | - The thread safety stuff. Async has issues, but the core
  | thread safety constructs (send, sync, mutex vs atomic, etc) are
  | just so well designed that rust is by far my favorite language
  | for writing synchronous, shared-memory threaded code. It's
  | quite possible to mess it up, but it's far easier to keep that
  | system in my head than any comparable one that I've used. Of
  | course shared-nothing is even easier, and rust lets you do that
  | too!
  | 
  | I don't use it for everything, but when I do encounter a thing
  | rust is good at, it's just a treat.
 
    | nneonneo wrote:
    | Rust has some amazing libraries, too. I recently found out
    | about `rayon`, and I applied it to a compute-heavy program I
    | was writing. It was literally a one-line change (as
    | promised!) to go from sequential to parallel, and I didn't
    | need to worry at all that there might be some data race
    | somewhere (unlike, say, #pragma omp parallel).
 
  | kccqzy wrote:
  | Sorry to disappoint you but if Rust had adopted higher-kinded
  | types they wouldn't need to write a function `try_for_each`
  | because it would just be a generic fold-and-collect-effect
  | function that works for all effects not just Try:
  | traverse_ :: Foldable t => (a -> ExceptT e IO b) -> t a ->
  | ExceptT e IO ()
  | 
  | Of course I'm not saying Rust should have this (there are good
  | reasons why this isn't a good fit for Rust, see http://smallcul
  | tfollowing.com/babysteps/blog/2016/11/09/asso...) but it really
  | caught my eye that you called `try_for_each` obscure; it could
  | have been an everyday function if it had a bit more
  | expressiveness.
 
    | vbarrielle wrote:
    | In my opinion a very good point about Rust is that it is
    | built by people who know these functional programming
    | concepts and why they are yseful, but are pragmatic enough to
    | give them names that are easier to grasp for folks who don't
    | know these concepts.
    | 
    | And it's possible the lack of higher kinded types, forcing
    | reimplementation, actually gave the opportunity to look for
    | frindlier names.
 
| lspears wrote:
| Why no Go?
 
  | ear7h wrote:
  | I'm guessing if you don't need something low-level/c-compatible
  | in Android you'd reach for Java/Kotlin since it's already
  | engrained in the ecosystem.
 
  | maeln wrote:
  | The GC I guess ? Rust is mostly replacing the C & C++ code that
  | is pretty low-level in the OS where a GC is not desirable or
  | even usable.
 
  | wiseowise wrote:
  | They already have managed language, why would you add another
  | one?
 
  | masklinn wrote:
  | Does not play well with anything else, and the primary langage
  | is Java/Kotlin, even making two "managed" languages interact
  | properly is difficult when both have well behaved ffi.
  | 
  | It would require rearchitecting everything to work with
  | separate processes and IPC, and that's got some overhead(s).
  | 
  | It also has memory safety issues around concurrency, and its
  | limited allowance for abstractions makes papering over those
  | complicated.
 
| [deleted]
 
| onei wrote:
| Not being aware of how vulnerabilities are detected and despite
| being a big fan of Rust, I wonder if there are other variables
| that drive down the ability to find bugs in the short term. If a
| researcher is only familiar with C and C++, is it possible that
| they're just ill equipped to find similar bugs in Rust?
 
  | insanitybit wrote:
  | There's definitely a learning curve for looking for vulns in
  | Rust vs C/C++, especially compared to C. Exploitation in
  | particular will be the trickier part, imo, since it requires
  | not just understanding the vuln but also the context and
  | reachability.
  | 
  | That said, there are a ton of ways that auditing for
  | vulnerabilities is just as easy or way easier. In particular,
  | most tooling for C/C++ can be applied to rust - fuzzers and
  | sanitizers, for example. Additionally, one only has to "grep
  | for unsafe" and work from there to find Rust vulns, which
  | largely amounts to "what are the assertions for this unsafe
  | block, are they complete, are they held?".
 
  | goodpoint wrote:
  | Not only that, they are also comparing new code with pretty old
  | code.
 
    | Manishearth wrote:
    | They're also explicitly tracking _new_ code by language, and
    | talking about memory safety vulnerabilities per year, and
    | they also link to [1] which talks about how most memory
    | safety bugs they get are in _new_ code.
    | 
    | Most of the graphs here are about new code.
    | 
    | [1]: https://security.googleblog.com/2021/04/rust-in-android-
    | plat...
 
      | estebank wrote:
      | It's also useful to look at the "rate of bugs per line of
      | new code" because even stablished, long stable projects
      | have code churn. Rare is the project that is unchancged,
      | frozen in bakelite, and any mild refactor can introduce
      | regressions or affect relied upon implicit invariants.
 
  | est31 wrote:
  | Rust programs can have vulnerabilities, but thankfully the
  | fuzzer scene is well developed. Recently a memory safety bug
  | was found in a Rust library (that used unsafe) and it turns out
  | the original C++ implementation had it too. So here, fuzzing
  | the Rust rewrite led to improvements in the original C++
  | library. I guess it's because there is higher interest in
  | increasing the safety of Rust programs.
  | 
  | https://dwrensha.github.io/capnproto-rust/2022/11/30/out_of_...
 
| hknmtt wrote:
| programming language developers always made compilers to just do
| that - compile the code. without actually checking the code for
| problems and allowed programmers to write faulty code. and now we
| have accepted these memory leaks and shooting oneself into one's
| foot as normal. so instead of investing time to make compilers
| output safe programs we had to wait for rust to come by and its
| "first time in history" compiler while it limits the programmers
| tremendously to do that along with the ugliest syntax ever
| invented. when a programmer looks at faulty code, the bug can be
| seen. sometimes easily, other time not as easy but it can be
| identified nevertheless. that means we, humans, can detect them.
| so why can't programs do the same while having way more computing
| power at their disposal for that particular task, along with
| language definition and type system? everyone keeps writing new
| languages and trying to reinvent the wheel in blue, red, purple
| color instead of solving the actual problem.
 
  | the_myth wrote:
  | I mean, rust devs are couple of nobodies and I don't think they
  | just let nobodies in on the C++ committee.
 
| stephc_int13 wrote:
 
___________________________________________________________________
(page generated 2022-12-01 23:00 UTC)