[HN Gopher] Memory safety is necessary, not sufficient
___________________________________________________________________
Memory safety is necessary, not sufficient
Author : weinzierl
Score : 54 points
Date : 2023-12-22 08:44 UTC (1 days ago)
(HTM) web link (steveklabnik.com)
(TXT) w3m dump (steveklabnik.com)
| weinzierl wrote:
| Regarding _" Now, I am not a politican, and these bills are huge,
| so I wasn't able to figure out how these bills do this
| specifically [..]"_, I think the relevant reference is on page
| 864 of [1]:
|
| _" SEC. 1613. POLICY AND GUIDANCE ON MEMORY-SAFE SOFT- WARE
| PROGRAMMING. (a) POLICY AND GUIDANCE.--Not later than 270 days
| after the date of the enactment of this Act, the Secretary of
| Defense shall develop a Department of Defense wide policy and
| guidance in the form of a directive memorandum to implement the
| recommendations of the National Security Agency contained in the
| Software Memory Safety Cybersecurity Information Sheet published
| by the Agency in November, 2022, regarding memory-safe software
| programming languages and testing to identify memory-related
| vulnerabilities in software developed, acquired by, and used by
| the Department of Defense."_
|
| The mentioned _" Software Memory Safety Cybersecurity Information
| Sheet"_ is probably [2] which explicitly lists _" C#, Go,
| Java(r), Ruby(tm), Rust(r), and Swift"_ as examples for memory
| safe languages.
|
| I'm still looking for the equivalent EU document and would be
| grateful for any hints.
|
| EDIT: I could not find any reference to memory safety in any of
| the EU documents but interestingly the _" Impact Assessment
| Report"_ [3] mentions Rust and Go specifically.
|
| [1] https://www.armed-
| services.senate.gov/imo/media/doc/fy24_nda...
|
| [2]
| https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...
|
| [3] https://ec.europa.eu/newsroom/dae/redirection/document/89545
| steveklabnik wrote:
| Thank you! I really appreciate it.
| zelon88 wrote:
| I don't think the government's goal in improving memory safety is
| because of Rust or any other particular technology.
|
| The government buys technology from wherever, and until recently
| they never really cared where they got it from. If they need a
| USB Emulator, they buy the same Chinese Gotek from Ebay that you
| or I buy, and they get the same "Driver CD" full of buggy, broken
| English software, written by one person for $27 over the course
| of about 7 hours. Same thing with DVR systems, access controls,
| network appliances, access points. I've worked on government
| projects that were using 20 year old, broken, encryption
| libraries on active web servers. And when brought to their
| attention the people who use it don't care, and the people who
| are capable of doing something about it will never find out
| because it's too much work to replace and nobody wants to take
| that Zoom call.
|
| I think the author is getting a little over-excited about Rust.
| Granted, they are a Rust developer. I'd love it if we could build
| everything in my favorite language. But the government doesn't
| want to replace everything with Rust. The government wants
| results. Period. It is the DOD, NSA, and CISA who need to become
| experts on how to realize those results. And they will probably
| release guidance that says "if you can't program securely in a
| memory unsafe language, don't use a memory unsafe language". The
| thing I think the author is missing is that nobody is going to
| mistaken "Made with RUST!" for "Impossible to cause undefined
| behavior!"
|
| You can be a terrible programmer and still create undefined
| behavior, insecure code, data leaks, or any number of other
| problems in a memory safe language.
|
| What the government is going to do is implement strict code
| import controls, similar to the export controls we already have.
| Purchasing departments will have to get software purchases signed
| off multiple times by qualified parties, and department leaders
| will have to prove that the technology they procure is adequately
| safe. In some situations I anticipate that means re-writing a
| bunch of code in Rust, and in other situations I'm sure that
| means hardening existing C. The majority of the government's
| security holes that need to be patched are coming from low
| quality unvetted imported technology, low quality self-written
| code, and code that should have been replaced 20 years ago. While
| it's exciting to think that this could mean a renaissance for the
| author's technology of choice, I just don't see it working out
| that way. If the government could write memory safe code, it
| would have. Rust isn't safe ENOUGH to save the government from
| itself alone.
| alilleybrinker wrote:
| Just a small clarification here. The author isn't just a fan of
| Rust. Steve was a member of the Rust Core Team for years and
| was co-author of the book "The Rust Programming Language,"
| which is the main recommended introductory text for the
| language.
| zelon88 wrote:
| I saw the authors credentials and I do respect them a lot.
| But to be fair, I'm sure the person who wrote the Go manual
| could have written the same blog post with the same outlook
| for the future only with Go in place of Rust. I'm trying to
| broaden the scope of conversation to a more holistic one,
| rather than just "this is our chance to take over the world!"
|
| Like my Gotek USB emulator reference. The device costs $50,
| and it's pretty much the ONLY option you have for emulating a
| floppy drive with a USB stick in a bunch of obsolete
| hardware. The software that it comes with was written by a
| Chinese high school student in C++ during a study break and
| it is about as insecure and sketchy as you would expect it to
| be.
|
| If you're the government looking to buy this, your choices
| are;
|
| 1. Buy this sketchy retroft device that is insecure and may
| be backdoored for a cost of $60.
|
| 2. Replace whatever needs the retrofit for a cost of $2m.
|
| 3. Write your own drivers for $100k.
|
| Currently they just use the $60 device. The upcoming policy
| changes will take that option off the table for a lot of
| agencies, forcing them to make wiser purchasing decisions. It
| doesn't automatically mean Rust wins the day, or that rust
| deserves to win the day. It means intelligent conversations
| must be had and difficult decisions have to be made that used
| to get avoided.
| alphager wrote:
| Nobody is claiming that rust wins the day. Memory-safe
| languages, of which rust is one of them, will get a boost.
| That's it.
| steveklabnik wrote:
| > But the government doesn't want to replace everything with
| Rust.
|
| To be clear, I don't think that they do. To be honest, I am
| mostly confused by your post, not because I disagree, but
| because I am unsure how you came to the conclusion that I
| believe these things.
| brabel wrote:
| Funny, because I came out with the almost opposite
| impression: that perhaps the legislators will require
| something stronger than even Rust to consider something
| "safe" because Rust still allows easy access to things like
| `unsafe` and FFI like most other languages - and true safety
| may require more than that.
|
| I think our biases, together with the lack of a firm
| conclusion in this post, leaves the door open to vastly
| different interpretations.
| marcosdumay wrote:
| Just like in every other kind of engineering, for software
| capability pulls the requirements.
|
| The only reason everybody is complaining about lack of memory
| safety now is because there are alternatives for every use
| case. Before Rust existed, it was seen as an inevitable issue
| that one must work with, not as a problem to solve.
| lowbloodsugar wrote:
| lol. The government doesn't want results, unless the result is
| siphoning as much public money into private pockets as
| possible.
| pornel wrote:
| I think it's underappreciated that Rust's `unsafe{}` doesn't
| exist in isolation. Rust has facilities for building safe
| abstractions on top of it, and has a culture of taking this
| abstraction layer seriously.
|
| Danger of unsafe features and FFI is usually conditional -- you
| can use a pointer only until some point, or only on a single
| thread, etc. A use of unsafe in Rust doesn't become "be careful!"
| kryptonite spreading around the program. It's possible to build
| walls around it to contain it completely.
|
| In Swift + unsafe or Java + JNI I've struggled building equally
| solid abstractions around FFI. They don't have "you can call it
| only once" or "you can't call go() after finish()" as a compile-
| time check. They don't have "you can use it only within this
| scope" (they may use a closure/callback to give access to an
| unsafe object, but these aren't hermetic, so that's a convention
| not a guarantee). Exposing objects to Swift or Java requires the
| higher level language to be in charge of their lifetime.
| mplewis9z wrote:
| I haven't had a chance to fully explore the new features and
| there are probably still some sharp edges, but the addition of
| non-copyable types and borrowing/consuming bindings in Swift
| 5.9 should bring it a lot closer to Rust in those respects,
| especially the hermeticity aspect. If you haven't experimented
| recently, might be worth doing - this is also one of the big
| focuses of the language in the near term, so there should be
| lots more progress coming too.
| mannuch wrote:
| I wonder what the author thinks about Swift's new C++ interop
| story? Since the Swift compiler includes Clang, and can thus
| compile both your C++ and Swift into LLVM IR, without the need
| for an FFI later between the two, couldn't this be the
| "Typescript for C++" that the author points out a space for? The
| Swift folks are very much thinking about Swift as a C++ successor
| that can be incrementally migrated to so I'm a bit surprised the
| author didn't discuss it further -- especially given Swift's
| spiritual similarities to Rust.
|
| There's a couple great talks on this by folks on the Swift team.
|
| John McCall at CppNow https://m.youtube.com/watch?v=lgivCGdmFrw
|
| Konrad Malawski at StrangeLoop 2023
| https://m.youtube.com/watch?v=ZQc9-seU-5k
| steveklabnik wrote:
| I do not know a ton about it. Thanks for the pointers.
|
| I kept up with Swift more in the old days, but it doesn't seem
| to have gained a ton of relevance outside of Apple platforms,
| which I don't develop for. Doesn't mean that I think that it's
| bad, just that that's why I haven't spent a lot of time with it
| yet.
| fweimer wrote:
| I agree with the sentiment. Consider a hypothetical variant of
| Python that requires using eval() (with the same behavior as in
| Python, so full Python expression support) for converting from
| strings to integers or floats. Or that implicitly calls eval() on
| list subscripts, to turn strings into integers. None of these
| changes impact memory safety, but it still makes it much more
| likely that common code has security vulnerabilities. (There is
| actually a widely used programming language with the eval-on-
| subscript feature ...)
|
| > While a Go program may exhibit what a Rust or C++ program would
| consider undefined behavior, and it does also consider it an
| error, the consequences are very different. You don't get time
| travel. You get 998 instead of 1,000.
|
| This isn't correct. Data races on multi-word objects of built-in
| type, such as slices and interfaces, actually have undefined
| behavior, in the sense that array bounds checking and type
| checking may break down.
|
| Russ Cox's old example still works if you disable optimizations:
| https://research.swtch.com/gorace
|
| It looks like some form of dead store elimination happens to
| eliminate the data race with current compilers. For now, it's
| possible to bring it back by adding a pointless atomic operation,
| like this: go func(){ for !done {
| k = i atomic.AddUint32(&global, 1) k = j
| } }()
| lambdaone wrote:
| Enforcing memory safety is good thing, even if it's not perfect;
| it's the first stage in the long-needed move from throw-it-in-a-
| bucket-and-hope-it-works "software engineering" toward proper
| formal-methods-driven actual software engineering.
|
| I feel complaining about it as insufficient is not the ideal way
| to push things forward. Instead, let's treat the progress on
| memory safety policy as a first victory in that process, and
| build on it.
| dgreensp wrote:
| I think it's worth emphasizing that the C spec's love of
| undefined behavior--if you do X by accident, anything can happen
| --and the apparently massive amount of memory-unsafe software
| that has been written that will just allocate 16 bytes on the
| stack and then read from a file descriptor until it encounters a
| null byte... are examples of things that aren't considered
| remotely sane or reasonable to a modern programmer or language
| designer. Any vague notion of "unsafe" in the context of a modern
| language--like saying well, if there's a syscall, maybe something
| unexpected could happen--doesn't compare to the bad decisions
| made by C and C programmers/culture that affect us today because
| we still use C code in our things.
|
| The deep, idiosyncratic flaws of C trace back to "worse is
| better." Few people remember or look up what "worse is better"
| actually meant. Wikipedia wrongly says it's a "less is more" sort
| of thing, and some people think it's about not being a
| perfectionist.
|
| But actually... actually actually, if you read the essay, it says
| "worse is better" means (paraphrasing) it's _more important that
| C compilers be easy to implement than easy to use_. Also, _it is
| more important that the implementation--or the design of the
| implementation--of a piece of software be simple than that it be
| correct. It is more important that it be simple than that it be
| consistent. It is more important that it be simple than that it
| be "complete" (for example, handle edge cases; it just needs to
| work in "most situations")._ This is not just anti-perfectionism,
| it is an objectively terrible set of engineering values. But
| there were so many different kinds of computers and operating
| systems back then--you didn't even know if a byte was 8 bits--
| that it helped a lot that C compilers could do whatever they
| wanted in many situations. And making it easy for C compiler
| implementers enabled C to spread far and wide. It was a very
| different world, and just being able to write in a higher-level
| language than assembly on a particular computer was a big deal.
| angiosperm wrote:
| Nobody has been able explain to me what would be lost if we
| defined data races to yield one of the values that had been
| written to the memory in the past, instead of being undefined. It
| is not as if any optimizer can see that you are racing and delete
| the code path that has it.
| atq2119 wrote:
| "One of the values written to memory" isn't really a thing when
| memory accesses can tear (e.g. because the values are 16 bytes
| large and are accessed using 8 byte memory ops). So it's not
| even necessarily about what would be lost, it's about what can
| be reasonably defined in the first place.
|
| If you restrict yourself to relaxed atomic loads and stores --
| i.e., memory accesses that are atomic in the sense that they
| cannot tear, but don't have much in the way of ordering
| guarantees -- then you do get "one of the values that had been
| written to the memory in the past".
|
| Aside from memory tearing, one other issue is that you
| generally want to be able to rematerialize loads (i.e., in the
| face of register pressure, you may want to turn one load of a
| value into multiple loads instead of loading it once, then
| spilling to the stack and reloading from the stack). But when
| the compiler rematerializes a load, then you don't get "one of
| the values written to memory". From the perspective of the
| original program it looks like you get some weird superposition
| of values.
| Gehinnn wrote:
| I'm pretty sure that you have either an undecidable problem or
| a non deterministic piece of code that sometimes computes some
| value, other times a different value, depending on how the
| threads are scheduled. Neither is good.
| amelius wrote:
| Our programs are growing so big by having so many (indirect)
| dependencies that we need a way to sandbox the libraries that we
| include from our main programs. This is the type of safety that
| I'm looking for, really.
___________________________________________________________________
(page generated 2023-12-23 23:00 UTC)