[HN Gopher] Memory Safe Languages in Android 13 ___________________________________________________________________ Memory Safe Languages in Android 13 Author : brundolf Score : 326 points Date : 2022-12-01 17:39 UTC (5 hours ago) (HTM) web link (security.googleblog.com) (TXT) w3m dump (security.googleblog.com) | mk89 wrote: | I am not a Rust or C++ fanboy, and I am happy that we are moving | towards a future where there are less memory bugs, but... are we | really? | | - https://www.infoq.com/news/2021/11/rudra-rust-safety/ | | - https://cve.report/vendor/rust-lang | | And you can find online similar links and research on the topic. | | All it takes is that you use that specific piece of code at the | wrong time, and that's it: your system which you once believed to | be safe is not anymore safe. And you know what? You don't even | know what a sanitizer is, because they told you that Rust is a | memory safe language and you don't need anything else than the | rust compiler - this is how I find 99% of today's articles about | Rust. | | Sure, today being Rust less used than C/C++ will clearly show | less CVEs. | | The question is ... once it's in the wild (and by this I mean | "major" libs or serious shit done in Rust) how can you prevent | such bugs without a runtime sanitizer? | | Beware that such CVEs can affect Rust Standard library as well, | not just an unknown library. | | Again, there is no way of escaping bad programming and bad | practices, no matter which language you use. Someone might argue | that in Python or Java you can still do bad stuff, however, the | likelihood is way lower, especially because most of your Java | libraries will very likely be written in Java - unless you know | it's using JNI under the hood etc. | IshKebab wrote: | Did you read this bit? | | > It could appear that these results undermine the belief that | Rust safety model represents an improvement over other | languages, e.g. C++, but this would not be correct, say the | researchers behind Rudra, who still consider Rust safety a | supreme improvement. | | They found ~100 security issues in 45k packages. That's clearly | better than C++. | mk89 wrote: | I didn't say it's not an improvement. I just wonder who will | you blame once you have a hacker exploiting that exact CVE | which you didn't know about because they sold you rust as | memory safe language, so you didn't take the time to run any | sanitizer or similar. | | Does Rust provide a way to check if you're using unsafe code? | What if I want to disable that? If I need to make a mission | critical software I need to be aware of what I am deploying. | If on the other hand we want Rust to be the new JS for | backend, then yes so be it, we improved over c++, well done. | bluGill wrote: | Rust would have prevented about half of the CVEs in C code | (I've seen a few different studies with somewhat different | results, half is close enough for discussion). The other | half is on you to write good code. | | Note that the half Rust would prevent tends to be less | impactful, still a CVE, but the exploit is less impactful | to end users. | mk89 wrote: | If we leave it to the programmer, what are we improving? | | We did a big improvement, but why can't we disable | "unsafe"? | | That would leave absolutely no margin for such errors. | masklinn wrote: | > We did a big improvement, but why can't we disable | "unsafe"? | | Because there are things which literally can not be safe, | and rust will not let you get away with pretending. | throwup wrote: | Rust has a culture where people don't use `unsafe` unless | absolutely necessary. That is generally good enough in my | experience. | | If you want to go further, you can disable unsafe in a | crate by adding #[forbid(unsafe)]. | | And if you need more control than that, there's probably | tooling out there that will help depending on what | exactly you need. | | https://github.com/rustsec/rustsec/tree/main/cargo-audit | | https://github.com/rust-secure-code/cargo-geiger | | https://github.com/crev-dev/cargo-crev | stouset wrote: | > I didn't say it's not an improvement. | | You... almost literally did? | | > I am happy that we are moving towards a future where | there are less memory bugs, but... are we really? | fiedzia wrote: | > they told you that Rust is a memory safe language and you | don't need anything else than the rust compiler - this is how I | find 99% of today's articles about Rust. | | It is - as long as you don't use unsafe. Which is very rare, so | we've made huge progress here already. Validation for cases | where unsafe is necessary is needed and welcomed, but doesn't | change the fact that 99% safe Rust is much better than 100% | unsafe C/C++. | | > Again, there is no way of escaping bad programming and bad | practices, no matter which language you use. | | Escape entirely maybe not. Eliminate most of it - definitely. | joshuamorton wrote: | Yes. | | They found 250 bugs after analyzing the entirety of rust and | all of it's packages. | | There are probably more memory safety bugs in the python | standard library and top 50k packages. | masklinn wrote: | The rust project itself also has an extremely aggressive CVE | policy (which many find too aggressive): if unsoundness is | found in an API it gets a CVE, no matter how convoluted, and | how unlikely it is to get into that situation, with | absolutely no guarantee of any code in the wild coming even | close to the unsoundness. | | Essentially, the Rust standard is that more or less every | line of the C++ standard is a CVE. | | Hell, the Rust project releases CVE for things other | languages literally just shrug about e.g. https://blog.rust- | lang.org/2022/01/20/cve-2022-21658.html | | The C++ people just go "lol nothing in std::filesystem is | safe we don't give a shit". The spec pretty much says it's UB | to have other programs interact with the filesystem: | http://eel.is/c++draft/fs.race.behavior#1.sentence-2 | [deleted] | steveklabnik wrote: | Many CVEs in the Rust ecosystem aren't filed by the Rust | project itself. Anyone can file a CVE, it does not require | involvement of upstream. | | That said things that happen in the language or standard | libraries like the one you linked, are often (but not | always!) filed by the project. | cryptonector wrote: | > Safety measures make memory-unsafe languages slow > > Mobile | devices have limited resources and we're always trying to make | better use of them to provide users with a better experience (for | example, by optimizing performance, improving battery life, and | reducing lag). Using memory unsafe code often means that we have | to make tradeoffs between security and performance, such as | adding additional sandboxing, sanitizers, runtime mitigations, | and hardware protections. Unfortunately, these all negatively | impact code size, memory, and performance. | | Even more evidence that the negative performance impact of bounds | checking is minimal, nay, it can even be positive. | kllrnohj wrote: | No it isn't. It's just evidence that it's a trade-off you might | want to make in order to achieve some other goal, specifically | security. | | But if "security" isn't remotely a concern for a given project | (like almost anything graphics / gaming related), this is not | at all evidence for changing anything. It _could_ be that Rust | 's optimizer eliminates the bounds checking so regularly as to | be a moot point, but _this_ isn 't saying anything of the sort. | It's saying that the cost, whatever it was, was judged to be | worth paying for the improved security _for these projects_ | masklinn wrote: | > But if "security" isn't remotely a concern for a given | project (like almost anything graphics / gaming related) | | Gaming platforms have gotten a lot less lenient over time, | and with pretty much every game these days having online | components, "security isn't remotely a concern" has become a | lot less true. | berkut wrote: | Sure, but then there's things like HPC / offline graphics / | simulation (VFX/CG), where performance is the end-all | concern (or memory efficiency sometimes at the expense of | CPU time), and security isn't a concern at all there, with | lots of things like random index lookups into sparse arrays | / grids, etc. I know for a fact that bound checks do make a | bit of a difference there, as the data's random, so the | branch predictors are close to useless in that situation... | lynndotpy wrote: | Security is absolutely a concern in these areas (except | maybe offline graphics). | | In my experiences with university HPC clusters, security | is very important because you have a lot of young | students with no Unix experience accessing the resources. | We've had real compromises of individual research | machines because of this. | | This happens all the time at research universities, but | it's not always public. In one public example from my | uni, hackers from China compromised a research machine, | which was used to attack IT infrastructure, which lead to | PII including SSNs being compromised. | berkut wrote: | That's security of the generic infrastructure the code's | running under though is it not? It's not security of say | CUDA kernel code being executed on a GPU? | | I'm talking about the actual HPC algorithm code _heavily_ | priortising performance (or in some cases memory | efficiency), at the expense of pretty much everything | else (other than correctness, obviously). | Ar-Curunir wrote: | If your high performance code running on a sensitive | cluster is vulnerable, then it opens up the rest of the | system to exploitation also. How is it a problem of the | infrastructure around the code, and not the code itself? | yosefk wrote: | Everybody who works with Maya, Flash (now Adobe Animate) | etc. knows that they crash all the time, and often | corrupt files so you back them up every hour or so. | Carmack insists, in a gaming context, to run heavyweight, | high-false-positive-rate static analyzers because users | don't like crashes. | | When C++ dies (which in 20 years it will, and I wasn't | that hopeful 20 years ago), people will look in the same | bewilderment at excuses made for its insane behavior as | they look now at mid-20th-century arguments against high- | level languages (and assemblers before them - like Mel | said, "you never know where it will put things so you'd | have to use separate constants.") | Taywee wrote: | > which in 20 years it will, and I wasn't that hopeful 20 | years ago | | That's too optimistic. C++ would easily die in 20 years | if it didn't already have 30+ years of still-active | legacy that can't easily be converted or rewritten. | | I've recently even had to start new projects in C++ | because platforms I depend on demand it or because I have | to interface with existing code and libraries that still | only exist as C++. I'm not a fan of the language by any | means, but I'll eat my shoe if it's "dead" in 20 years | for anything except maybe greenfield development. | yosefk wrote: | Dead - no, dying COBOL-style - quite possibly. | berkut wrote: | At least in VFX, at the high-end Maya's only really used | for modelling/UVing/layout now, other apps have taken | over the rendering/lighting side of things... | | But anyway, in my experience a lot of the crashes are | often due to quickly hacked together plugins for the | various DCCs written for artists, that don't have good | error checking or testing, and it's not completely clear | to me how that situation's going to improve that much | with something like Rust, if the same programmer time | constraints are going to exist in writing them: i.e. I | think it's very likely people will just unwrap() their | way to getting things to compile instead of correctly | handling errors, so it will be the same situation from | the artists' perspective: technically it may be a panic | rather than a segfault, but from the artists' | perspective, it will likely be identical and take the DCC | down. | estebank wrote: | panics can be caught and the presence of those unwraps | come with enough data that filing a bug report upstream | is helpful enough to fix the bug. | berkut wrote: | Sure, but that (we do it) happens currently with C/C++ | and signal handler traps which gather the callstack and | collate them: the issue isn't usually that we don't know | the crashes aren't happening or having the call stacks - | the issue is hacky code that was written for one purpose | is now being used for other things it wasn't designed for | (because it is useful to artists, despite its | limitations), and there isn't the time to go back and | write it properly for the new expanded use-case. That's | my point: a new safer language isn't going to improve | much in this area without more development time provided | to write better code, given the time constraints are | going to be the same as they are currently. | estebank wrote: | It does change the situation if the plugin throws an | exception on errors instead of causing a segfault that | brings down the parent application. | estebank wrote: | It's not just about bounds checks. I am way more agressive | about borrowing fields of other types, particularly mutable | borrows in ways that I wouldn't attempt in C to protect | myself from future code from breaking invariants I'd have to | rely on. This means I can write the hyper optimized version | of an algorithm on any language, but I'm more likely to even | attempt it in Rust. | masklinn wrote: | An other bit I first saw observed by Armin Ronacher and | which is indeed quite common is that Rust does not require | you to be defensive (and pay the price) around protected | resources e.g. you can hand out references to rc'd types | (avoiding refcount traffic) or mutex'd, and you know it's | safe, if a bit constraining. | bluGill wrote: | I take it the opposite: C programmers out of abundance of | caution of putting in bounds checks for code that will never | be called with out of bound data. As such rust is eliminating | code that is being manually written. If you don't write the | bounds check in C, and rust for the equivalent determines | that the bounds check isn't needed the code should be the | same (to the assembly level). However if you write a bounds | check in C the optimizer might not eliminate it. | kllrnohj wrote: | Can you point to any such bounds check in C that an | optimizer cannot eliminate but it can eliminate the | equivalent one in Rust? | | I'm sure it's possible to construct such a thing, but I | cannot imagine it ever being common enough to show up on | any sort of head to head comparison. | tialaramex wrote: | I would guess all the aliasing stuff will get you. In C | it's very difficult for the compiler to know whether two | pointers are aliased, if we change X maybe Y changes too | (because actually X and Y were the same). In Rust if we | can _write_ to it then it isn 't aliased, and if we can't | write to it then nobody can change it, thus changing X | definitely can't change Y and the emitted machine code is | sometimes simpler as a result, doing what you naively | expected rather than what the C needs to do just in case | you're crazy and there is an alias. | | Now, in modern C you can _say_ you don 't have aliasing, | but you're probably wrong and so there's a high risk when | you do that you now get "impossible" bugs because you | swore to the optimiser that if X changes, Y is | unaffected, then created a situation where that wasn't | true and now your program has no defined meaning, which | is going to be tricky to debug. So, on the whole C | programmers do not use this, indeed in places like the | Linux kernel they even turn off the C standard's very | minimal aliasing rules (which forbid aliasing objects of | different types), they just don't trust themselves. | kllrnohj wrote: | But the compiler doesn't need to care in that case | because it's not bounds checking those pointers in the | first place in C. So that's not going to give you slow C | code from bounds checking that the optimizer failed to | eliminate. | | Like yeah there's aliasing changes, but in "idiomatic" | C/C++ how is that getting you bounds checking that's not | being optimized away fairly consistently? | Gankra wrote: | there's almost no bounds checking in rust code before the | optimizer even looks at it because we use iterators and | not goofy manually indexed for loops that are begging you | to make a typo that crashes your code :) | kllrnohj wrote: | Yeah but idiomatic modern C++ is also using iterators and | even before that there's no bounds checking to eliminate | in the first place since operator[] is unchecked so the | optimizer can't be struggling to eliminate it since it's | not there. | | The question isn't "does Rust have bad bounds checking | optimizations" but rather "what is this mythical heavily- | bounds-checked C code that the compiler can't optimize | away?" | Gankra wrote: | No the claim is always that Rust "must" be slower than | C/C++ because it has pervasive bounds checking for array | indexing. | | Then people insist on wanting to replace every x[i] in | prod with x.get_unchecked(i) only to learn that, not only | was that indexing not slowing the code down (the branch | is perfectly predictable in a correct program!), but | actually any difference is so in the noise that the | random perturbation is worse (or that the asserts were | actually adding extra facts for more profitable | optimizations in llvm). | | There is definitely specific hot loops with weird access | patterns where it can be high impact but those are the | exception, not the rule, as the Android team | demonstrated. | stouset wrote: | Trivially, anything using the Iterator trait. | | I don't know that I've _ever_ actually manually indexed | an array over years of using Rust. | berkut wrote: | In the HPC / offline graphics / simulation world, there's | lots of things like sparse arrays / grids, where you | index into compacted grids and iterators wouldn't be that | practical in that scenario (i.e. one single item, | although for things like filtering with surrounding cells | they can still be useful sometimes), and bounds checks do | make a bit of a difference there (it's definitely | measureable above the noise threshold), and due to the | random nature of the data, the branch predictors don't | help avoid the overhead. | stouset wrote: | Sure, I know there's paradigms where manual indexing is | important. GP asked for an example where bounds-checking | could be eliminated in Rust, so I gave the first one I | thought of. | kllrnohj wrote: | I don't think your answer is relevant to the question: | | > Can you point to any such bounds check in C | bluGill wrote: | I wonder how much of the positive performance is just because | we have not proved that some impossible case is really | impossible and so we have if statements checking for a | situation that mathematically cannot happen just out of | caution. (note that in many cases we don't even have the | theoretical tools to prove the code) | | Though that makes non-memory safe code more reliable in the | case of a bit flip. (this is not a serious advantage - only | some bit flips can be prevented this way) | mark_l_watson wrote: | How does Swift compare to Rust in safety? I read that Swift is | only memory safe in single threaded environments, which is not | ideal. | | I was very enthusiastic about Rust about 4 years ago but decided | to learn Swift instead as a new "cool non-Lisp language" to | learn. Seeing an recent article on writing Python in Rust made me | wish that I had chosen differently. | | I found this article made me feel better about security. I expect | that increasing use of memory safe languages will lock down | public infrastructure and software, making everyone safer. | blub wrote: | No such luck in having some technical discussion or at least a | link to the sources. | | If the Rust community can be insufferable when trying to sell | Rust at any and every opportunity, Lord have mercy when they see | any kind of success because the preening and puffing will have no | end. This blog post will live forever in the annals of Rust. | | On the other hand I'm not surprised to see that it's written by | the security team and not a development team. Same pattern as | with Microsoft: security specialists tend to get obsessed by | their subject matter (just like many Rust programmers), end up | hating C and C++ and see them as the source of all problems (just | like many Rust programmers). | | In reality, C and C++ were the saviors of Android and Google | reluctantly had to conjure the NDK to make up for a severe lack | of performance compared to the iPhone. Note how even in the | current Android they mention improving the UI performance and | having less "jank". Without C++ Android would have been DoA, but | it doesn't look like there will be a blog post thanking C++ any | time soon :-) | | I can't take seriously reports about the benefits of a tool that | don't mention any of the downsides. When the devs post a blog | cursing the troubles they had getting Java and C++ and Rust to | work together and pitying themselves for having to read both C++ | and Rust, then we'll be getting closer to the truth. | Ar-Curunir wrote: | Yes, C++ was critical to Android in the past, when there was no | memory-safe low level systems language that could provide an | alternative. Now there is, so they're using it, and finding | benefits, and writing about those benefits. | | What should they do instead, write an eulogy to C++? | goodpoint wrote: | I'll be downvoted for pointing out that comparing C++ with Rust | without further context can be made into a false dichotomy. | | Some people are posting the article around the Internet as | evidence that Rust solved security. Instead, there are many other | memory safe languages around and there has been thousands in the | past. Additionally, many security issues are not due to memory | safety. Please keep that in mind when making comparisons. | | EDIT: of course, 2 minutes and I'm downvoted down to -2 | insanitybit wrote: | You're being downvoted because your points are directly | addressed and refuted with evidence in the article. They | explicitly address different vulnerability classes. | burntsushi wrote: | Can you link to _anyone_ with any modicum of credibility | declaring that this article is evidence that "Rust solved | security"? I'll be the first to point out that memory safety | related vulnerabilities are merely a subset (albeit a big one) | of all possible vulnerabilities. | goodpoint wrote: | That's what I wrote. | burntsushi wrote: | ... yes? And I'm asking you, who is saying that? _You_ | said: | | > Some people are posting the article around the Internet | as evidence that Rust solved security. | | OK, so show me. Let's see all these people declaring that | this is "evidence that Rust solved security." | | I think it's far more likely that you're exaggerating what | folks are saying to make them appear far more unreasonable | than they actually are. But we can't know that unless you | actually show your work, now can we? | est31 wrote: | > there are many other memory safe languages around and there | has been thousands in the past. | | Yes, and in fact they write about how they are replacing C/C++ | with Kotlin or Java. All three are memory safe languages. But | Rust is the only low level language of the three. This is | Rust's killer feature. Of course, JavaScript is memory safe and | so is Lua. But they are high level languages. | | > Additionally, many security issues are not due to memory | safety. | | I think it depends on the domain the program is in. If you are | a program managing some security property, like e.g. TLS | encryption, then virtually any bug you have might be a security | issue. Same goes for OS kernels. But if you are e.g. an image | decoder library, then there is little security impact if your | output is a weirdly colored image. But memory safety issues | might still be a problem for your decoder library. | | Overall the number being cited is 70/30, as in, 70% of security | issues are memory safety ones, and 30% are ones which are not | about memory safety. | | https://www.zdnet.com/article/microsoft-70-percent-of-all-se... | | So you can reduce the number of security issues by 70%, isn't | that great? | bmicraft wrote: | It really sounds like you didn't read the article at all. It | explicitly mentions Java/Kotlin in one breath with rust almost | any chance it gets. | PoignardAzur wrote: | Preemptively complaining about downvotes is a great way to get | downvotes. | | That doesn't make you a martyr. | kangalioo wrote: | But I think other memory safe languages don't have C++-like | performance, right? | goodpoint wrote: | There's been many, for example Ada/SPARK, D, Nim, Java, | Kotlin, Swift. | kllrnohj wrote: | I can't speak to the others, but Java & Kotlin do not at | all have C++-like performance, especially not in anything | beyond a toy level benchmark. | | And even in those toy level benchmarks (like | https://benchmarksgame- | team.pages.debian.net/benchmarksgame/... ), there's a clear | divide between C/C++/Rust & everything else. | goodpoint wrote: | The claim that performance are comparable only on "toy | benchmarks" is false. Additionally, most of such simple | benchmarks are not representative for real-life workload, | and anyways the initial point was about safety. | | Anyhow the whole HN conversation is now a trainwreck | where any dissenting opinion is downvoted so there's no | point to continue. | nneonneo wrote: | - Ada: good example, has substantial uses in certain areas. | However, certain things are quite difficult, e.g. compile- | time checked pointers (a la Rust's borrow-checked | references). | | - D, Nim: neither provide strong memory safety guarantees. | D has a safe subset, but it's not default (see | https://news.ycombinator.com/item?id=12391720). Nim allows | you to turn checks off at runtime. Both Nim and D generally | use a GC. | | - Java/Kotlin are not low-level: requires GC, and not often | used for low-level systems programming. Great languages, | but different niche. | thesuperbigfrog wrote: | >> Ada: good example, but not usually used for low-level | systems programming. Has substantial uses in certain | areas. | | Ada is _primarily_ used for low-level systems programming | and embedded systems: | | https://learn.adacore.com/courses/intro-to- | ada/chapters/intr... | | Substantial portions of the Ada standard deal with | systems programming and low-level representation on | hardware: | | http://www.ada-auth.org/standards/22rm/html/RM-C.html | | http://www.ada-auth.org/standards/22rm/html/RM-13-1.html | nneonneo wrote: | Thanks for the correction. I will update my comment | accordingly. | nequo wrote: | This seems like a straw man. Who said that Rust is the only | memory-safe language? The title of the post itself uses | "languages" in plural. | modshatereality wrote: | is this a good way to spend developer time? How about *removing* | all of the middle-man bloatware instead of wasting how many dev- | years rewriting it (edit: and effectively making it even LESS | maintainable now that it's in some new niche language with a | vastly smaller dev pool). just give me the direct linux | experience we all deserve instead of this garbo spamflinger | middlewear that google leverages to keep you dependent on their | build methodology and discourage cooperation with other | competitive linux-based system. | | edit2: wow mods hard at work, already removed one dissenting | post. | bmicraft wrote: | > and effectively making it even LESS maintainable now that | it's in some new niche language with a vastly smaller dev pool | | How is any language supposed to grow if you're only allowed to | use it once everybody does? Somebody has to be first (and | google isn't, not by a long shot) | modshatereality wrote: | You should at least wait until there is more than one | working/usable compiler for the language if you're going to | start making systemic changes to your multi-billion-dollar | code base responsible for the commerce of multiple billions | of people on the planet. It's a weird move at this point for | google to be making(edit: considering go is already supported | on multiple compilers). | insanitybit wrote: | "It should have two compilers" is a pretty arbitrary | benchmark for production readiness. I'd suggest the | benchmark be based on, idk, something with any fucking | meaning. | modshatereality wrote: | >something with any fucking meaning | | So you claim to have a better metric, feel free to share | it? | | site broken and wont let me reply any more: "shipped into | production" is meaningless, compilers are directly | related to language community and complexity. | insanitybit wrote: | How about numerous companies shipping Rust to production | for years? That metric is actually related to risk with | regards to shipping rust in production, unlike number of | compilers, which signifies nothing. | binkHN wrote: | From the bottom of the article: | | > As Android migrates away from C/C++ to Java/Kotlin/Rust, we | expect the number of memory safety vulnerabilities to continue to | fall. Here's to a future where memory corruption bugs on Android | are rare! | lzooz wrote: | How about speed from going from C/C++ to Java/Kotlin? Have they | considered that even? | summerlight wrote: | It will most likely be C/C++ -> Rust for performance critical | modules. | HideousKojima wrote: | I'm assuming that's why they have Rust in the mix there, for | where performance is still critical. | insanitybit wrote: | See the section "Safety measures make memory-unsafe languages | slow" | latenightcoding wrote: | I wonder if their efforts to leverage modern chip capabilities to | address memory safety (e.g: ARM memory tagging) contributed to | that drop of memory safety vulnerabilities | GuB-42 wrote: | I didn't realize there was so much C and C++ in Android, I | thought most of it was Java. Maybe they are just talking about | the core system (including the Linux kernel and Java runtime) and | not all the builtin apps. | kllrnohj wrote: | Much of the graphics, camera, media, bluetooth, wifi, input | handling, etc... stacks are native. There's a massive amount of | native code in Android below the veneer of the Java API that | apps are given. | | Many of the higher level constructs are then in Java/Kotlin, | though, like the builtin apps, system ui, activity & window | managers, etc... | Octokiddie wrote: | > This matches the expectations published in our blog post 2 | years ago about the age of memory safety vulnerabilities and why | our focus should be on new code, not rewriting existing | components. | | and | | > As we noted in the original announcement, our goal is not to | convert existing C/C++ to Rust, but rather to shift development | of new code to memory safe languages over time. | | For those working on C/C++ code bases, how does the incremental | addition of Rust work in practice? What strategies and tools come | in handy? Also, what are some good case studies where Rust was | introduced to add new features, but still needed to work within a | system mainly composed of C/C++? I've seen some of the first | steps with Linux, but I'm thinking of a project where more | substantial additions have been made. | antonok wrote: | Brave Browser has some Rust components too (e.g. the adblocking | engine). Rust in C++ works very well for components with a | small, well-defined API surface that involve a lot of logic. | You only need to build a small FFI layer for the direct | interfaces between the two languages. CXX [1] makes this even | easier, too. | | Brave is definitely _not_ aiming to convert the entire browser | to Rust, but it 's increasingly chosen for new development. | | [1] https://cxx.rs/ | halpmeh wrote: | I imagine it works just like FFI works in other languages. | Compile a c-archive and link against it. | bluGill wrote: | I've only started scratching the surface, but that rust really | wants you to use Cargo, while we have our own homegrown package | manager, and cmake creates a lot of friction. | | I can tell you that bad programmers can write bad code in Rust. | TheNorthman wrote: | > I can tell you that bad programmers can write bad code in | Rust. | | Of course. The question rust users seem to put forth is that | bad programmers write _better_ (not good) rust code than C | code. | | That bad programmers write bad code is to expected. That is, | after all, a likely explanation for why they're bad. | nneonneo wrote: | I would argue that the type system does make it somewhat | more difficult for bad programmers to do egregiously bad | things in the language. A carefully written library can be | quite difficult to misuse (at least, without panics or | using unsafe code in the user code, both of which are easy | to catch in code review). | | Rust has no null/nil pointers. Instead, it has nullable | types (Option<T>), 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<T>` 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<PathBuf> 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 "<stdin>", line 2 in <module> 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<Self>) {} } impl Foo | { // instance, refcounted fn | foo(self: Rc<Self>) {} } | 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)