|
| 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) |